【CodeVS1163】访问艺术馆

Description

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

Input

第1行是警察赶到得时间,以s为单位。第2行描述了艺术馆得结构,是一串非负整数,成对地出现:每一对得第一个数是走过一条走廊得时间,第2个数是它末端得藏画数量;如果第2个数是0,那么说明这条走廊分叉为两条另外得走廊。数据按照深度优先得次序给出,请看样例

Output

输出偷到得画得数量

Sample Input

60

7 0 8 0 3 1 14 2 10 0 12 4 6 2

Sample Output

2

HINT

s<=600

走廊的数目<=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]);
}

 

posted @ 2016-03-26 22:00  mengyue  阅读(332)  评论(0编辑  收藏  举报