【CodeVS1163】访问艺术馆
Description
![](http://codevs.cn/media/image/problem/1163.jpg)
Input
第1行是警察赶到得时间,以s为单位。第2行描述了艺术馆得结构,是一串非负整数,成对地出现:每一对得第一个数是走过一条走廊得时间,第2个数是它末端得藏画数量;如果第2个数是0,那么说明这条走廊分叉为两条另外得走廊。数据按照深度优先得次序给出,请看样例Output
Sample Input
7 0 8 0 3 1 14 2 10 0 12 4 6 2
Sample Output
HINT
走廊的数目<=100
题解
根据数据建立二叉树
定义f(tot,k)表示
花费不超过tot的时间,在以第k个结点为根的子树中,
能得到的画的数量。
时间tot的构成:
到达及离开子树的时间: 2*t[k].v
分别在左右子树中的时间: x y
f(tot,k)=Max{f(x,t[k].l)+f(y.r)}
x+y+t[k].v+t[k].v=tot
0<=x<=j-2*t[k].v
初始值:
对于叶结点
f(i,k)=0 (i<2*t[k].v+5)
f(i,k)=Min{t[k].c,(i-t[k].v-t[k].v)/5} (i>=2*t[k].v+5)
上面这段是粘的
其实我不太会 抄的题解。。
#include<iostream> #include<cstdio> using namespace std; struct node{ int l,r; int c,v; }t[110]; int f[610][110]; int q[110]; int cnt=0,s; void buildtree(int k){ int x; scanf("%d%d",&t[k].v,&x); ++cnt; if (!x){ t[k].l=cnt; buildtree(t[k].l); t[k].r=cnt; buildtree(t[k].r); }else t[k].c=x; } int main(){ scanf("%d",&s); buildtree(0); int head=0,tail=1;q[0]=0; for (;head<tail;head++){ int cur=q[head]; if (t[cur].l) q[tail++]=t[cur].l; if (t[cur].r) q[tail++]=t[cur].r; } for (int i=--tail;i>=0;i--){ int cur=q[i]; if (t[cur].l==0&&t[cur].r==0){ for (int j=2*t[cur].v;j<=s;j++) if ((j-2*t[cur].v)/5<t[cur].c) f[j][cur]=(j-2*t[cur].v)/5; else f[j][cur]=t[cur].c; }else{ for (int j=2*t[cur].v;j<=s;j++) for (int x=0;x<=j-2*t[cur].v;x++) f[j][cur]=max(f[j][cur],f[x][t[cur].l]+f[j-2*t[cur].v-x][t[cur].r]); } } printf("%d",f[s][0]); }