hdu1011 Starship Troopers 树形DP

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011

思路:很明显的树形背包

定义dp[root][m]表示以root为根,派m个士兵的最优解,那么dp[root][m]=max(dp[root][m],dp[root][k]+dp[son][j]) k+j<=m son为root 的孩子

树形dp的思路一般就是着父亲和孩子节点之间的转移关系,然后从dfs到叶子节点,然后开始从叶子节点向上进行DP

最重要的就是建树和dfs求解的过程,如果掌握了怎样建树和怎样进行DP,那么树形DP就会发现很简单了。。。。

加油!!!ACMer

代码如下:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 #define MAX 110
 7 int n,m;
 8 int dp[MAX][MAX];
 9 int tol;
10 class node
11 {
12    public:
13    int to;
14    int next;
15 };
16 node edge[MAX*3];
17 int head[MAX];
18 int bugs[MAX];
19 int brain[MAX];
20 int vis[MAX];
21 void Build_Tree(int u,int v)
22 {
23         edge[tol].to=v;
24         edge[tol].next=head[u];
25         head[u]=tol++;
26 }
27 void init()
28 {
29         memset(head,-1,sizeof(head));
30         memset(dp,0,sizeof(dp));
31         memset(vis,0,sizeof(vis));
32         memset(bugs,0,sizeof(bugs));
33         memset(brain,0,sizeof(brain));
34         tol=0;
35 }
36 void dfs(int root)
37 {
38    vis[root]=1;
39    int cost=(bugs[root]+19)/20;//important
40    for(int i=cost;i<=m;i++)
41            dp[root][i]=brain[root];
42    for(int i=head[root];i!=-1;i=edge[i].next)
43    {
44            if(vis[edge[i].to]) continue;
45            int son=edge[i].to;
46            dfs(son); 
47 
48            for(int j=m;j>=cost;j--)
49            {
50                    for(int k=1;k+j<=m;k++)
51                        if(dp[son][k])
52                                dp[root][j+k]=max(dp[root][j+k],dp[son][k]+dp[root][j]);
53            }
54    }
55 }
56 int main()
57 {
58         while(scanf("%d%d",&n,&m)!=EOF)
59         {
60              if(n==-1||m==-1) break;
61              init();
62              for(int  i=1;i<=n;i++)
63                   scanf("%d%d",&bugs[i],&brain[i]);
64              for(int i=1;i<n;i++)
65              {
66                      int u,v;
67                      scanf("%d%d",&u,&v);
68                      Build_Tree(u,v);
69                      Build_Tree(v,u);
70              }
71             if(m==0) {cout<<"0"<<endl;continue;}
72             dfs(1);
73             cout<<dp[1][m]<<endl;
74 
75         }
76         return 0;
77 }
View Code

 

posted on 2013-08-18 14:37  GyyZyp  阅读(188)  评论(0编辑  收藏  举报

导航