码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1561 树形dp+分组背包

时间:2015-03-10 11:37:12      阅读:137      评论:0      收藏:0      [点我收藏+]

标签:

卡在为什么是分组背包的问题上,看了下面几句话理解了

题意就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值。

一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m)时选最多的宝物,而一个子节点中只可以选择一个状态进行转移,每个节点有若干个子节点,问题就转换为分组背包,几个子节点就是几个分组背包,体积是选几个地点,价值是宝物价值。      

状态转移方程: dp[v][1] = Money[v]; (v为叶子节点)
                   dp[v][j] = max(dp[v][j],dp[v][j-i] + dp[k][i] );(v为非叶子节点,j表示用户个数,i为容量,k为v的子节点,)

 

 

 1 /*
 2 HDU  1561 The more, The Better
 3 树形DP + 分组背包
 4 建立一颗数,选了子节点,必选父亲结点。
 5 对于每个结点,它的子结点就是个分组背包
 6 */
 7 #include<stdio.h>
 8 #include<algorithm>
 9 #include<string.h>
10 #include<iostream>
11 using namespace std;
12 const int MAXN=220;
13 struct Node
14 {
15     int to;
16     int next;
17 };
18 Node edge[MAXN];//建立的有向数,和结点数一样就可以了
19 int tol;
20 int head[MAXN];//头结点
21 int value[MAXN];//每个结点的宝物数量
22 
23 int dp[MAXN][MAXN];//dp[i][j]表示在以i为根的子树上,攻克j个结点获得的最大价值
24 
25 void init()
26 {
27     memset(head,-1,sizeof(head));
28     tol=0;
29     memset(dp,0,sizeof(dp));
30 }
31 
32 void add_edge(int a,int b) //建立一条a->b的有向边
33 {
34     edge[tol].to=b;
35     edge[tol].next=head[a];
36     head[a]=tol++;
37 }
38 
39 int n,m;
40 
41 void dfs(int u)
42 {
43     dp[u][1]=value[u];//选一个肯定选自己这个结点
44     for(int i=head[u];i!=-1;i=edge[i].next)
45     {
46         int v=edge[i].to;
47         dfs(v);
48         //分组背包,外层是对所有的组(参考背包九讲)
49         for(int k=m;k>=1;k--)  //for v <- V to 0
50         //下面这个循环必须是j<k结束,不能取等号,因为至少需要留一个点来取u点
51           for(int j=1;j<k;j++) // do for 所有的属于当前组
52             dp[u][k]=max(dp[u][k],dp[u][k-j]+dp[v][j]);
53     }
54 }
55 
56 int main()
57 {
58     int a,b;
59     while(scanf("%d%d",&n,&m)!=EOF)
60     {
61         if(n==0&&m==0)break;
62         init();
63         for(int i=1;i<=n;i++)
64         {
65             scanf("%d%d",&a,&b);
66             value[i]=b;
67             add_edge(a,i);
68         }
69         value[0]=0;
70         m++;//虚拟构造了结点0
71         dfs(0);
72 
73         printf("%d\n",dp[0][m]);
74     }
75     return 0;
76 }

 

hdu 1561 树形dp+分组背包

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4325352.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!