hdu1561 树形DP

                                    The more, The Better

                                                                 Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

                                                                 Total Submission(s): 2753    Accepted Submission(s): 1637

Problem Description
ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?
 
Input
每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。
 
Output
对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。
 
Sample Input
3 2
0 1
0 2
0 3
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
0 0
 
Sample Output
5
13
思路:自己建立一个根root,使森林的根都成为root的孩子,然后树形dfs+简单背包

0-1背包裸代码:

for i=1..N

    for v=V..0

        f[v]=max{f[v],f[v-c[i]]+w[i]};

状态转移方程:f[root][k]=max(f[root][k],f[root][k-j]+dp[u][j]);

m是个数,j是存几个,f[i][j]表示的是以i为根攻克j个城堡(且这j个城堡必须是它子树上的,不包括它本身),dp[i][j]表示的是是以i为根攻克j个城堡(且这j个城堡必须是它子树上的,一定它本身,ans[i]表示每个城堡的宝物,所以一定有dp[i][1]=ans[i];)。

for(int k=m;k>=0;k--)

for(int j=0;j<=k;j++)

     f[root][k]=max(f[root][k],f[root][k-j]+dp[u][j]);

更新f[root][0~m]数组,然后全部更新完之后更新dp[root][0~m]

如图所示样例2,先从root0点访问33没有孩子,执行更新dp操作,因为所以叶子都满足dp[i][0~m]=ans[i],所以dp[3][0~m]都等于ans[3],以下同理。

返回到root,更新f[0][m~0]

访问root-->2-->7-->6,访问到叶子,更新dp[6][0~m]。返回7,更新f[7][m~0]

7-->5,更新叶子节点dp[5][0~m]

5-->7,再次更新f[7][m~0]

7-->2,更新dp[7][0~m],返回2节点,更新f[2][m~0]

2-->4,更新叶子节点dp[4][0~m]

4-->2,更新f[2][m~0]

2-->1,更新dp[1][0~m]

1-->2,更新f[2][m~0]

2-->root,更新dp[2][0~m]

更新f[0][m~0],更新dp[0][0~m]

单步执行:

 

View Code
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2
-->0
-->3
dp[3][1] 4=f[3][0] 0+ans[3] 4

dp[3][2] 4=f[3][1] 0+ans[3] 4

dp[3][3] 4=f[3][2] 0+ans[3] 4

dp[3][4] 4=f[3][3] 0+ans[3] 4

dp[3][5] 4=f[3][4] 0+ans[3] 4

f[0][4] 4=max(f[0][4] 0,f[0][3] 0+dp[3][1] 4
f[0][4] 4=max(f[0][4] 4,f[0][2] 0+dp[3][2] 4
f[0][4] 4=max(f[0][4] 4,f[0][1] 0+dp[3][3] 4
f[0][4] 4=max(f[0][4] 4,f[0][0] 0+dp[3][4] 4

f[0][3] 4=max(f[0][3] 0,f[0][2] 0+dp[3][1] 4
f[0][3] 4=max(f[0][3] 4,f[0][1] 0+dp[3][2] 4
f[0][3] 4=max(f[0][3] 4,f[0][0] 0+dp[3][3] 4

f[0][2] 4=max(f[0][2] 0,f[0][1] 0+dp[3][1] 4
f[0][2] 4=max(f[0][2] 4,f[0][0] 0+dp[3][2] 4

f[0][1] 4=max(f[0][1] 0,f[0][0] 0+dp[3][1] 4


-->2
-->7
-->6
dp[6][1] 6=f[6][0] 0+ans[6] 6

dp[6][2] 6=f[6][1] 0+ans[6] 6

dp[6][3] 6=f[6][2] 0+ans[6] 6

dp[6][4] 6=f[6][3] 0+ans[6] 6

dp[6][5] 6=f[6][4] 0+ans[6] 6

f[7][4] 6=max(f[7][4] 0,f[7][3] 0+dp[6][1] 6
f[7][4] 6=max(f[7][4] 6,f[7][2] 0+dp[6][2] 6
f[7][4] 6=max(f[7][4] 6,f[7][1] 0+dp[6][3] 6
f[7][4] 6=max(f[7][4] 6,f[7][0] 0+dp[6][4] 6

f[7][3] 6=max(f[7][3] 0,f[7][2] 0+dp[6][1] 6
f[7][3] 6=max(f[7][3] 6,f[7][1] 0+dp[6][2] 6
f[7][3] 6=max(f[7][3] 6,f[7][0] 0+dp[6][3] 6

f[7][2] 6=max(f[7][2] 0,f[7][1] 0+dp[6][1] 6
f[7][2] 6=max(f[7][2] 6,f[7][0] 0+dp[6][2] 6

f[7][1] 6=max(f[7][1] 0,f[7][0] 0+dp[6][1] 6


-->5
dp[5][1] 1=f[5][0] 0+ans[5] 1

dp[5][2] 1=f[5][1] 0+ans[5] 1

dp[5][3] 1=f[5][2] 0+ans[5] 1

dp[5][4] 1=f[5][3] 0+ans[5] 1

dp[5][5] 1=f[5][4] 0+ans[5] 1

f[7][4] 7=max(f[7][4] 6,f[7][3] 6+dp[5][1] 1
f[7][4] 7=max(f[7][4] 7,f[7][2] 6+dp[5][2] 1
f[7][4] 7=max(f[7][4] 7,f[7][1] 6+dp[5][3] 1
f[7][4] 7=max(f[7][4] 7,f[7][0] 0+dp[5][4] 1

f[7][3] 7=max(f[7][3] 6,f[7][2] 6+dp[5][1] 1
f[7][3] 7=max(f[7][3] 7,f[7][1] 6+dp[5][2] 1
f[7][3] 7=max(f[7][3] 7,f[7][0] 0+dp[5][3] 1

f[7][2] 7=max(f[7][2] 6,f[7][1] 6+dp[5][1] 1
f[7][2] 7=max(f[7][2] 7,f[7][0] 0+dp[5][2] 1

f[7][1] 6=max(f[7][1] 6,f[7][0] 0+dp[5][1] 1


dp[7][1] 2=f[7][0] 0+ans[7] 2

dp[7][2] 8=f[7][1] 6+ans[7] 2

dp[7][3] 9=f[7][2] 7+ans[7] 2

dp[7][4] 9=f[7][3] 7+ans[7] 2

dp[7][5] 9=f[7][4] 7+ans[7] 2

f[2][4] 2=max(f[2][4] 0,f[2][3] 0+dp[7][1] 2
f[2][4] 8=max(f[2][4] 2,f[2][2] 0+dp[7][2] 8
f[2][4] 9=max(f[2][4] 8,f[2][1] 0+dp[7][3] 9
f[2][4] 9=max(f[2][4] 9,f[2][0] 0+dp[7][4] 9

f[2][3] 2=max(f[2][3] 0,f[2][2] 0+dp[7][1] 2
f[2][3] 8=max(f[2][3] 2,f[2][1] 0+dp[7][2] 8
f[2][3] 9=max(f[2][3] 8,f[2][0] 0+dp[7][3] 9

f[2][2] 2=max(f[2][2] 0,f[2][1] 0+dp[7][1] 2
f[2][2] 8=max(f[2][2] 2,f[2][0] 0+dp[7][2] 8

f[2][1] 2=max(f[2][1] 0,f[2][0] 0+dp[7][1] 2


-->4
dp[4][1] 1=f[4][0] 0+ans[4] 1

dp[4][2] 1=f[4][1] 0+ans[4] 1

dp[4][3] 1=f[4][2] 0+ans[4] 1

dp[4][4] 1=f[4][3] 0+ans[4] 1

dp[4][5] 1=f[4][4] 0+ans[4] 1

f[2][4] 10=max(f[2][4] 9,f[2][3] 9+dp[4][1] 1
f[2][4] 10=max(f[2][4] 10,f[2][2] 8+dp[4][2] 1
f[2][4] 10=max(f[2][4] 10,f[2][1] 2+dp[4][3] 1
f[2][4] 10=max(f[2][4] 10,f[2][0] 0+dp[4][4] 1

f[2][3] 9=max(f[2][3] 9,f[2][2] 8+dp[4][1] 1
f[2][3] 9=max(f[2][3] 9,f[2][1] 2+dp[4][2] 1
f[2][3] 9=max(f[2][3] 9,f[2][0] 0+dp[4][3] 1

f[2][2] 8=max(f[2][2] 8,f[2][1] 2+dp[4][1] 1
f[2][2] 8=max(f[2][2] 8,f[2][0] 0+dp[4][2] 1

f[2][1] 2=max(f[2][1] 2,f[2][0] 0+dp[4][1] 1


-->1
dp[1][1] 2=f[1][0] 0+ans[1] 2

dp[1][2] 2=f[1][1] 0+ans[1] 2

dp[1][3] 2=f[1][2] 0+ans[1] 2

dp[1][4] 2=f[1][3] 0+ans[1] 2

dp[1][5] 2=f[1][4] 0+ans[1] 2

f[2][4] 11=max(f[2][4] 10,f[2][3] 9+dp[1][1] 2
f[2][4] 11=max(f[2][4] 11,f[2][2] 8+dp[1][2] 2
f[2][4] 11=max(f[2][4] 11,f[2][1] 2+dp[1][3] 2
f[2][4] 11=max(f[2][4] 11,f[2][0] 0+dp[1][4] 2

f[2][3] 10=max(f[2][3] 9,f[2][2] 8+dp[1][1] 2
f[2][3] 10=max(f[2][3] 10,f[2][1] 2+dp[1][2] 2
f[2][3] 10=max(f[2][3] 10,f[2][0] 0+dp[1][3] 2

f[2][2] 8=max(f[2][2] 8,f[2][1] 2+dp[1][1] 2
f[2][2] 8=max(f[2][2] 8,f[2][0] 0+dp[1][2] 2

f[2][1] 2=max(f[2][1] 2,f[2][0] 0+dp[1][1] 2


dp[2][1] 1=f[2][0] 0+ans[2] 1

dp[2][2] 3=f[2][1] 2+ans[2] 1

dp[2][3] 9=f[2][2] 8+ans[2] 1

dp[2][4] 11=f[2][3] 10+ans[2] 1

dp[2][5] 12=f[2][4] 11+ans[2] 1

f[0][4] 5=max(f[0][4] 4,f[0][3] 4+dp[2][1] 1
f[0][4] 7=max(f[0][4] 5,f[0][2] 4+dp[2][2] 3
f[0][4] 13=max(f[0][4] 7,f[0][1] 4+dp[2][3] 9
f[0][4] 13=max(f[0][4] 13,f[0][0] 0+dp[2][4] 11

f[0][3] 5=max(f[0][3] 4,f[0][2] 4+dp[2][1] 1
f[0][3] 7=max(f[0][3] 5,f[0][1] 4+dp[2][2] 3
f[0][3] 9=max(f[0][3] 7,f[0][0] 0+dp[2][3] 9

f[0][2] 5=max(f[0][2] 4,f[0][1] 4+dp[2][1] 1
f[0][2] 5=max(f[0][2] 5,f[0][0] 0+dp[2][2] 3

f[0][1] 4=max(f[0][1] 4,f[0][0] 0+dp[2][1] 1


dp[0][1] 0=f[0][0] 0+ans[0] 0

dp[0][2] 4=f[0][1] 4+ans[0] 0

dp[0][3] 5=f[0][2] 5+ans[0] 0

dp[0][4] 9=f[0][3] 9+ans[0] 0

dp[0][5] 13=f[0][4] 13+ans[0] 0

13

 

代码:

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define N 205
 4 int n,m,edgeNum=0;
 5 int ans[N],dp[N][N],f[N][N];
 6 int visit[N],head[N];
 7 struct Line{int v,next;}edge[N];
 8 int max(int a,int b){return a>b?a:b;}
 9 void add(int u,int v)
10 {
11     edge[edgeNum].v=v;
12     edge[edgeNum].next=head[u];
13     head[u]=edgeNum++;
14 }
15 void dfs(int root)
16 {
17     visit[root]=1;
18     for(int i=head[root];i!=-1;i=edge[i].next)
19     {
20         int u=edge[i].v;
21         if(!visit[u])
22         {
23             dfs(u);
24             for(int k=m;k>=0;k--)
25               for(int j=0;j<=k;j++)
26               f[root][k]=max(f[root][k],f[root][k-j]+dp[u][j]);
27         }
28     }
29     for(int i=1;i<=m+1;i++)
30       dp[root][i]=f[root][i-1]+ans[root];
31 }
32 int main()
33 {
34     int a,b;
35     while(scanf("%d%d",&n,&m)!=EOF)
36     {
37         if(n==0&&m==0) break;
38         edgeNum=ans[0]=0;
39         memset(f,0,sizeof(f));
40         memset(dp,0,sizeof(dp));
41         memset(head,-1,sizeof(head));
42         memset(visit,0,sizeof(visit));
43         for(int i=1;i<=n;i++)
44         {
45             scanf("%d%d",&a,&b);
46             ans[i]=b;
47             add(a,i);
48         }
49         dfs(0);
50         printf("%d\n",dp[0][m+1]);
51     }
52 }

 

posted @ 2012-07-23 01:01  _sunshine  阅读(1093)  评论(0)    收藏  举报