P1270 “访问”美术馆
这道题感觉是树形DP“青春版”
就只用深搜和回溯(回溯的时候干干DP之事)就可以过
遍历到叶子的时候将其特殊处理一下
要注意几点:首先是每条路都要走两次(小偷总不能在管里头过夜),其次是最后一秒(不可以和阿sir撞个满怀)
最后给出代码(详细注解)
#include<iostream>
#include<cstdio>
using namespace std;
int f[100100][610];
int ls[100100],rs[100100];
int t,tot;
void build(int now)//dfs
{
int x,y;//x代表路径长度
scanf("%d%d",&x,&y);
if(y==0)
{
ls[now]=++tot;build(ls[now]);
rs[now]=++tot;build(rs[now]);
for(int i=x*2+1;i<=t;i++)//从走完这条走廊的时间到最后
for(int j=0;j<=i-x*2;j++)
//左儿子分配j的时间,右二子分配(i-2*x-j),也就是走完之前的走廊分配给儿子的时间减去左儿子分配到的时间
f[now][i]=max(f[now][i],f[ls[now]][j]+f[rs[now]][i-2*x-j]);
}
else
{
for(int i=x*2+5;i<=min(x*2+y*5,t);i++)f[now][i]=(i-x*2)/5;
//这是叶子节点,所以只管偷画(应该可以不用这个min)
for(int i=x*2+y*5+1;i<=t;i++)f[now][i]=f[now][i-1];
//画不够偷注意补齐喔
}
}
int main()
{
scanf("%d",&t);
build(0);
printf("%d",f[0][t-1]);
return 0;
}