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;
}

posted on 2012-02-18 16:50  夜->  阅读(201)  评论(0编辑  收藏  举报