记得wikioi开站不久的时候,我做这题被吓住了。后来发现没什么难度。
首先dfs序记录结点信息。
Left为左孩子 right为右孩子
time表示走廊的时间 cost表示价值(如果为0 表示为分岔口)
int dfs()
这题要详细说一下。
如果记录到leaf结点
那么记录下编号old_leaf
leaf++
表示读入就要读入下一个节点
那么左孩子=dfs()
右孩子=dfs()
(dfs是有返回值的,表示节点的编号,在递归当中就可以记录孩子节点。这是一种处理技巧,知道就好。)
如果f[r][s]表示r节点在剩余s秒时的最大价值。
那么通过这个通道需要Tree[r][s].time的时间
因为不仅要进去,还有出来。那么就剩余s-Tree[r].time*2
枚举i表示左子树遍历i秒,则右子树剩余s-Tree[r].time*2-i
那么f[r][s]=max{f[Tree[r].left][i]+f[Tree[r].right][s-Tree[r].time*2-i]};
如果r为叶子节点
那么如果剩下的画在有限的时间内拿完,就会刚刚好拿到Tree[r].cost个
如果偷不完,说明剩下s-Tree[r].time2的时间,那么就可以拿Int(s-Tree[r].time*2)5个Int()表示下取整
因为如果进去可能被警察抓到,所以有可能不进入这个分叉点。
所以可以简写为
首先dfs序记录结点信息。
Left为左孩子 right为右孩子
time表示走廊的时间 cost表示价值(如果为0 表示为分岔口)
int dfs()
这题要详细说一下。
如果记录到leaf结点
那么记录下编号old_leaf
leaf++
表示读入就要读入下一个节点
那么左孩子=dfs()
右孩子=dfs()
(dfs是有返回值的,表示节点的编号,在递归当中就可以记录孩子节点。这是一种处理技巧,知道就好。)
如果f[r][s]表示r节点在剩余s秒时的最大价值。
那么通过这个通道需要Tree[r][s].time的时间
因为不仅要进去,还有出来。那么就剩余s-Tree[r].time*2
枚举i表示左子树遍历i秒,则右子树剩余s-Tree[r].time*2-i
那么f[r][s]=max{f[Tree[r].left][i]+f[Tree[r].right][s-Tree[r].time*2-i]};
如果r为叶子节点
那么如果剩下的画在有限的时间内拿完,就会刚刚好拿到Tree[r].cost个
如果偷不完,说明剩下s-Tree[r].time2的时间,那么就可以拿Int(s-Tree[r].time*2)5个Int()表示下取整
因为如果进去可能被警察抓到,所以有可能不进入这个分叉点。
所以可以简写为
max(0,min((s-Tree[r].time*2)/5,Tree[r].cost))
#include<stdio.h>
#include<iostream>
#include<memory.h>
using namespace std;
const int MAX_N = 601;
const int root = 1;
struct node
{
int time;
int cost;
int left;
int right;
}Tree[MAX_N];
int f[MAX_N][MAX_N];
int S;
int leaf = 0;
int input()
{
int old_leaf=++leaf;
scanf("%d %d",&Tree[leaf].time,&Tree[leaf].cost);
if(!Tree[leaf].cost) Tree[old_leaf].left=input(),Tree[old_leaf].right=input();
return old_leaf;
}
int init()
{
scanf("%d",&S);
input();
memset(f,-1,sizeof(f));
}
int work(int r,int s)
{
if (f[r][s]!=-1) return f[r][s];
if (Tree[r].cost) return max(0,min((s-Tree[r].time*2)/5,Tree[r].cost));
int tmp = 0;
int i;
for (i=0;i<=s-Tree[r].time*2;i++)
tmp = max(tmp,work(Tree[r].left,i)+work(Tree[r].right,s-Tree[r].time*2-i));
return f[r][s]=tmp;
}
int put()
{
printf("%d",f[root][S]);
}
int main()
{
init();
work(root,S);
put();
return 0;
}