访问艺术馆 codevs1163 树形dp

40 篇文章 0 订阅

Description


皮尔是一个出了名的盗画者,他经过数月的精心准备,打算到艺术馆盗画。艺术馆的结构,每条走廊要么分叉为二条走廊,要么通向一个展览室。皮尔知道每个展室里藏画的数量,并且他精确地测量了通过每条走廊的时间,由于经验老道,他拿下一副画需要5秒的时间。你的任务是设计一个程序,计算在警察赶来之前(警察到达时皮尔回到了入口也算),他最多能偷到多少幅画。

Solution


题目很裸了已经o(︶︿︶)o

显然给出的是一颗二叉树,那么考虑树形dp。设 f[i][j] 为i节点j时间偷多少幅画,那么转移有三种,分别从左子树走,右子树走,两边一起走。两边走的情况枚举一下分配时间就行了

Code


#include <stdio.h>
#define rep(i, st, ed) for (int i = st; i <= ed; i += 1)
#define N 4001
#define S 1001
int f[N][S], l[N], r[N], p[N][N], cnt;
inline void add(int now, int cnt, int w){
    if (!l[now]){
        l[now] = cnt;
    }else if (!r[now]){
        r[now] = cnt;
    }
    p[now][cnt] = w;
}
int s;
inline void init(int t){
    rep(i, 1, t){
        rep(j, i * 5, i * 5 + 4){
            f[cnt][j] = i;
        }
    }
}
inline void dfs1(int now){
    int w, t;
    scanf("%d%d", &w, &t);
    cnt += 1;
    add(now, cnt, w * 2);
    if (t){
        init(t);
    }else{
        dfs1(cnt);
    }
    scanf("%d%d", &w, &t);
    cnt += 1;
    add(now, cnt, w * 2);
    if (t){
        init(t);
    }else{
        dfs1(cnt);
    }
}
inline int max(int x, int y){
    return x>y?x:y;
}
inline void dfs2(int now){
    if (l[now]){
        dfs2(l[now]);
    }
    if (r[now]){
        dfs2(r[now]);
    }
    if (!l[now] && !r[now]){
        return;
    }
    rep(j, 1, s){
        f[now][j] = max(f[now][j], f[l[now]][j - p[now][l[now]]]);
        f[now][j] = max(f[now][j], f[r[now]][j - p[now][r[now]]]);
        rep(kl, 1, j - 1){
            int kr = j - kl;
            f[now][j] = max(f[now][j], f[l[now]][kl - p[now][l[now]]] + f[r[now]][kr - p[now][r[now]]]);
        }
    }
}
int main(void){
    scanf("%d", &s);
    int n = 0;
    cnt = 2;
    int w, t;
    scanf("%d%d", &w, &t);
    l[1] = 2;
    p[1][2] = w * 2;
    dfs1(2);
    dfs2(1);
    printf("%d\n", f[1][s]);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值