访问艺术馆

来源:互联网 发布:淘宝电商如何拉人 编辑:程序博客网 时间:2024/04/30 12:03

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

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

输出描述 Output Description
输出偷到得画得数量

样例输入 Sample Input
60

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

样例输出 Sample Output
2

数据范围及提示 Data Size & Hint
s<=600

走廊的数目<=100

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <utility>using namespace std;struct srr{  int lch,rch,val,cost;}t[1000];pair<int,int>a[1000];int dp[1000][1000];void build(int &m)//建树{    int rt=m;    t[rt].cost=2*a[rt].first;//往返。我们必须保证它能够回到原来的点。    t[rt].val=a[rt].second;    if(a[m].second)    {        t[rt].lch=t[rt].rch=-1;//叶子        return;    }        t[rt].lch=m+1;        build(++m);        t[rt].rch=m+1;        build(++m);}int dfs(int rt,int time)//rt表示当前所在的节点位置,time是所余的时间{    if(dp[rt][time]!=-1)return dp[rt][time];//记忆化    if(time==0)return dp[rt][time]=0;    if(t[rt].lch==-1)    {        int c;        if(t[rt].val*5<=time-t[rt].cost)c=t[rt].val;        else c=(time-t[rt].cost)/5;//最多能拿下的画的数量        return dp[rt][time]=c;    }    dp[rt][time]=0;    int tt=time-t[rt].cost;    for(int i=0;i<=tt;i++)    {        int s1=dfs(t[rt].lch,i);        int s2=dfs(t[rt].rch,tt-i);        dp[rt][time]=max(dp[rt][time],s1+s2);    }    return dp[rt][time];}int main(){    int time;    cin>>time;    int n=0,m=0;    while(scanf("%d%d",&a[n].first,&a[n].second)!=EOF)n++;    build(m);    memset(dp,-1,sizeof(dp));    dfs(0,time);    printf("%d\n",dp[0][time]);    return 0;}
0 0
原创粉丝点击