题目背景
神偷对艺术馆内的名画垂涎欲滴准备大捞一把。
题目描述
艺术馆由若干个展览厅和若干条走廊组成。每一条走廊的尽头不是通向一个展览厅,就
是分为两个走廊。每个展览厅内都有若干幅画,每副画都有一个价值。经过走廊和偷画都是
要耗费时间的。
警察会在n 秒后到达进口,在不被逮捕的情况下你最多能得到的价值。
输入输出格式
输入格式:
第一行一个整数 n(n≤600)。
第二行若干组整数,对于每组整数(t,x),t 表示进入这个展览厅或经过走廊要耗费 t
秒的时间,若x>0 表示走廊通向的展览厅内有x 幅画,接下来
x对整数(w,c)表示偷一幅价值为 w 的画需要 c秒的时间。若
x=0 表示走廊一分为二。(t,c≤5; x≤30)
输入是按深度优先给出的。房间和走廊数不超过 300 个。
输出格式:
仅一个整数,表示能获得的最大价值。
输入输出样例
说明
来源:改编
注意警察?是到达进口的,所以要算往返时间,不能刚好在时刻n到达出口
一开始我把(n-1)>>1,后来发现自己把偷东西的钱也算了两✌遍
嗯,读入的时候递归读入,如果某些值在搜索的时候会被改变,要存一下呐,每次都搞错?.
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#define nn 311
using namespace std;
int node,e,n;
int fir[nn],nxt[nn<<1],to[nn<<1],w[nn],co[nn<<1];
long long dp[nn][611];
int read()
{
int ans=0,f=1;char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)) {ans=ans*10+ch-'0';ch=getchar();}
return ans*f;
}
void add(int a,int b,int c)
{
nxt[++e]=fir[a];fir[a]=e;to[e]=b;co[e]=c;
nxt[++e]=fir[b];fir[b]=e;to[e]=a;co[e]=c;
}
void init(int o)
{
int t=read(),x=read(),tt,w,c;
add(o,++node,t<<1);
if(!x) //有两个分叉,要读两次,node会变所以要先存起来
{
tt=node;
init(tt);
init(tt);
}
else
{
for(int i=1;i<=x;i++)
{
w=read();c=read();
for(int j=n;j>=c;j--)
dp[node][j]=max(dp[node][j],dp[node][j-c]+w);
}
}
}
void dfs(int o,int fa)
{
for(int i=fir[o];i;i=nxt[i])
if(fa!=to[i])
{
dfs(to[i],o);
for(int j=n;j>=0;j--)
for(int k=co[i];k<=j;k++)
dp[o][j]=max(dp[o][j],dp[o][j-k]+dp[to[i]][k-co[i]]);
int debug=1;
}
}
int main()
{
n=read()-1;
init(++node);
dfs(1,0);
printf("%lld",dp[1][n]);
return 0;
}