http://acm.hdu.edu.cn/showproblem.php?pid=1011
一个寒假没做题了 手生了 对于树形DP我一般用孩子兄弟的思路
还是英语不行呀 读题读不懂
是所走路径的叶子结点的话 需留下一个兵才能获得洞中brain
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
using namespace std;
struct node
{
struct next *next;
}head[101]; //链表头
struct next
{
int number;
struct next *next;
}; //表身
struct baseinformation
{
int bugnumber;
int brainnumber;
int neednum;
}baseinfor[101]; //每个洞的信息
int maxans[101][101]; //以 i 洞为根结点的树和他的兄弟树 形成的森林 有 j 个兵时的最优解
bool visited[101]; //是否来过
int N = 0;
int M = 0; //N 为洞数 M为兵数
inline void free() //释放链表
{
struct next *t;
for(int i = 1; i<=N ; i++)
{
head[i].next=NULL;
while(head[i].next!=NULL)
{
t = head[i].next;
head[i].next = t->next;
delete t;
}
}
}
int Dfs(struct next *t,int j)
{
if(t==NULL||j==0)
return 0;
int i=t->number;
if(visited[i]==true) //此洞已经走过
{
return Dfs(t->next,j);
}
if(maxans[i][j]!=-1) //以求过
return maxans[i][j];
visited[i]=true;
maxans[i][j] = Dfs(t->next,j); //不要此洞的 brain
visited[i]=false;
for(int l=0;l<=j-baseinfor[i].neednum;l++) //要此洞的brain
{
visited[i]=true;
if(baseinfor[i].bugnumber==0&&l==0) //如果此结点为所走的叶子结点 且为空洞
{
maxans[i][j] = max(maxans[i][j],Dfs(t->next,j-1)+baseinfor[i].brainnumber); //留下一个兵
}
else //否则
{
maxans[i][j] = max(maxans[i][j],Dfs(head[i].next,l)+Dfs(t->next,j-baseinfor[i].neednum-l)+baseinfor[i].brainnumber); //遍历所有情况
}
visited[i]=false;
}
return maxans[i][j];
}
int main()
{
int i = 0;
int j = 0;
int l = 0;
struct next *Tnode = NULL;
while(scanf("%d %d",&N,&M)!=EOF)
{
if(N==-1&&M==-1)
break;
memset(maxans,-1,sizeof(maxans));
for(i = 1; i<=N; ++i)
{
scanf("%d %d",&baseinfor[i].bugnumber,&baseinfor[i].brainnumber);
baseinfor[i].neednum = (baseinfor[i].bugnumber+19)/20;
}
for(l = 1; l<N; ++l)
{
scanf("%d %d",&i,&j);
Tnode = new next;
Tnode->number = j;
Tnode->next = head[i].next;
head[i].next = Tnode;
Tnode = new next;
Tnode->number = i;
Tnode->next = head[j].next;
head[j].next = Tnode;
}
memset(visited,false,sizeof(visited));
memset(maxans,-1,sizeof(maxans));
if(baseinfor[1].neednum>M||M==0)//无法通过第一个洞
{
cout<<"0"<<endl;;
}
else
{
visited[1] = true;
cout<<baseinfor[1].brainnumber+Dfs(head[1].next,M-baseinfor[1].neednum)<<endl;
}
free();
}
return 0;
}