[2016.7.test1] T2 偷天换日 [codevs 1163 访问艺术馆(类似)]

来源:互联网 发布:柯杰律师事务所知乎 编辑:程序博客网 时间:2024/04/30 10:06

偷天换日
(steal.c/pas/cpp limit 1s 64M)

【问题描述】
神偷对艺术馆内的名画垂涎欲滴准备大捞一把。艺术馆由若干个展览厅和若干条走廊组成。每一条走廊的尽头不是通向一个展览厅,就是分为两个走廊。每个展览厅内都有若干幅画,每副画都有一个价值。经过走廊和偷画都是要耗费时间的。警察会在n秒后到达进口,在不被逮捕的情况下你最多能得到的价值。
【输入文件】
第一行一个整数 n
第二行若干组整数,对于每组整数(t,x),t表示进入这个展览厅或经过走廊要耗费t秒的时间,若x>0表示走廊通向的展览厅内有x幅画,接下来x对整数(w,c)表示偷一幅价值为w的画需要c秒的时间。若x=0表示走廊一分为二。
输入是按深度优先给出的。
【输出文件】
仅一个整数,表示能获得的最大价值。
【输入样例】
50
5 0 10 1 10 1 5 0 10 2 500 1 1000 2 18 1 1000000 4
【输出样例】
1500
【数据规模】
n≤600
t,c≤5;
x≤30
房间和走廊数不超过300个。
【提示】
样例的输入对应于下图

这里写图片描述

codevs 1163 是本题弱化。

CV 1163 AC code:

#include <iostream>#include <cstring>#define ref(i,x,y) for(int i=x;i<=y;i++)#define def(i,x,y) for(int i=x;i>=y;i--)#define smax(i,j) i=max(i,j)//要善于用#defineusing namespace std;int tim,len,ans,f[101][601];int dfs(int fa)//返回这个结点序号{    int l,v;    len++;    int son=len;//这个结点序号,在最后返回    cin>>l>>v;//l是路径长度,v是藏画数量    l*=2;//路径要来回走,乘2    if (v==0)//不是叶子节点    {        int s1,s2;        s1=dfs(son);//左孩子        s2=dfs(son);//右孩子        ref(i,0,tim-l)//只走左边或只走右边            f[son][i+l]=max(f[s1][i],f[s2][i]);        ref(i,0,tim-l)//枚举左孩子耗费时间            ref(j,0,tim-l-i)//枚举右孩子耗费时间                smax(f[son][i+j+l],f[s1][i]+f[s2][j]);//两边都走        def(i,tim,5*v)//根据贪心策略,非叶子结点的画要取完            smax(f[son][i],f[son][i-5*v]+v);    }    else //是叶子节点        ref(i,1,v)//取i个画像            f[son][i*5+l]=i;    return son;//返回值,方便记录父亲左孩子和右孩子的序号}int main(){    cin>>tim;    memset(f,0,sizeof f);//养成好习惯    dfs(0);//深搜中输入    ref(i,0,tim)//取最优答案        smax(ans,f[1][i]);    cout<<ans;}

升级版偷天换日:
ACcode

#include <iostream>#include <iomanip>#include <fstream>#include <stdlib.h>#include <time.h>#include<cstring>#include<cstdio>#include<vector>#include<string>#include<algorithm>#include <limits.h>#include<cmath>#include<map>#include<queue>#include<set>using namespace std;#define N 100005#define M 100005#define LL long long//为自己加油O(∩_∩)O~const long long  mod =1000000007;int T;vector<int> v[333];struct node{    int w,c;};vector<node> dian[333];int len[333];int tot=0;void init(int fa){    tot++;    int t,x;    scanf("%d%d",&t,&x);    len[tot]=t;    v[fa].push_back(tot);    if (x>0){        int w,c;        for (int j=0;j<x;j++){            scanf("%d%d",&w,&c);            dian[tot].push_back(node{w,c});        }    }else {        int now=tot;        init(now);        init(now);    }}int dp[333][602];int f[602];void suan(int pos){    if (v[pos].empty()){        for (int j=0;j<dian[pos].size();j++){            int w=dian[pos][j].w,c=dian[pos][j].c;            for (int k=600-c;k>=0;k--){                dp[pos][k+c]=max(dp[pos][k+c],dp[pos][k]+w);            }        }        return;    }else {        int l=v[pos][0],r=v[pos][1];        suan(l);        suan(r);        memset(f,0,sizeof(f));        for (int j=0;j+2*len[l]<=600;j++) dp[pos][j+2*len[l]]=f[j+2*len[l]]=dp[l][j];        for (int j=0;j+2*len[r]<=600;j++) {            for (int k=0;k+j+2*len[r]<=600;k++){                dp[pos][k+j+2*len[r]]=max(dp[pos][k+j+2*len[r]],f[k]+dp[r][j]);            }        }    }}int main(){    freopen("steal.in","r",stdin);    freopen("steal.out","w",stdout);    scanf("%d",&T);    T-=1;    init(0);    suan(1);    if (T-len[1]*2>=0) printf("%d\n",dp[1][T-2*len[1]]);    else printf("0\n");    return 0;}
1 0
原创粉丝点击