HDU 1561

The more, The Better

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5618    Accepted Submission(s): 3345

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

Author

8600

Source

HDU 2006-12 Programming Contest

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<algorithm>
 6 #include<vector>
 7 using namespace std;
 8
 9 const int maxn=205;
10 int n,m;
11 bool visit[maxn];
12 int value[maxn];
13 int dp[maxn][maxn],dp0[maxn][maxn];
14 vector<int> G[maxn];
15
16 void dfs(int t)
17 {
18     if(visit[t]) return ;
19     visit[t]=1;
20     dp0[t][0]=0;
21     int num=G[t].size();
22     for(int i=0;i<num;i++)//t的第i个儿子
23     {
24         int son=G[t][i];
25         for(int j=m;j>=0;j--)//在i这个子树中选出j个
26             for(int k=0;j+k<=m;k++)
27             {
28                 if(dp0[t][j]!=-1){
29                     if(!visit[son]) dfs(son);
30                     int a=dp[son][k];
31                     dp0[t][j+k]=max(dp0[t][j+k],dp0[t][j]+a);
32                 }
33             }
34     }
35      for(int i=0;i<=m;i++)
36          if(dp0[t][i]!=-1) dp[t][i+1]=dp0[t][i]+value[t];
37 }
38 int main()
39 {
40   //  freopen("in.txt","r",stdin);
41     int a,b;
42     while(1){
43         scanf("%d%d",&n,&m);
44         memset(dp,-1,sizeof(dp));
45         memset(dp0,-1,sizeof(dp0));
46         //printf("%d ",dp[0][0]);
47         memset(visit,0,sizeof(visit));
48         memset(value,0,sizeof(value));
49         if(!n&&!m) break;
50         for(int i=0;i<maxn;i++) G[i].clear();
51         for(int i=1;i<=n;i++)
52         {
53             scanf("%d%d",&a,&b);
54             G[a].push_back(i);
55             value[i]=b;
56         }
57         dfs(0);
58         printf("%d\n",dp[0][m+1]);
59     }
60     return 0;
61 }
时间: 2024-10-13 01:15:19

HDU 1561的相关文章

HDU 1561&amp;HDU 3449 一类简单依赖背包问题

HDU 1561.这道是树形DP了,所谓依赖背包,就是选A前必须选B,这样的问题.1561很明显是这样的题了.把0点当成ROOT就好,然后选子节点前必须先选根,所以初始化数组每一行为该根点的值.由于多选了0点,所以记得把m++. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int MAXN=22

HDU 1561 ——The more, The Better(有依赖的树形DP)

题目分析: 攻占城堡所能获得的最多宝物,但是有个限制,要想攻占某个城堡前必须先攻占另一个城堡 思路: 建图,新建一个根节点为0,那么题目就变为要想取得子节点必须先取得它的父亲节点 今天为了解决这个问题,看了下背包九讲中的有依赖的背包,刷了道模板题. 大概思路是:要想取得附件必须先取主件,主件要么取,要么不取,取得话要怎么分配给附件,用01背包处理附件,然后再把每个主件分组背包 树形的依赖主要是附件是个集合,附件还有附件.森林的概念 根据DP的思想,我们先dfs到叶,01背包操作 即可.只是每次d

HDU 1561 The more ,The Better

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4960    Accepted Submission(s): 2927 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

初涉分组背包 HDU 1561 The more,The better

给出一个森林,每棵树均为一组物品,首先推出每棵树可以组成的物品种类. 然后是基本的分组背包模板. 即 最外层枚举组数,次外层枚举背包容量,内层枚举物品体积. 对于每棵树有 ans[root][i+j] = ans[root][ i ] + ans[son][ j ]. 题水数据也水,不多说了. #include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #incl

hdu 1561 The more, The Better 树状DP

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5844    Accepted Submission(s): 3476 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝

[HDU 1561] The more, The Better (树形dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 题目大意:ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡.你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗? 设计状态 dp[u][i] 代表以u为根的,选择i个的最大收获 状态转移 dp[u][j+k] =

HDU 1561 (树形DP+背包)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1561 题目大意:从树根开始取点.最多取m个点,问最大价值. 解题思路: cost=1的树形背包. 有个虚根0,取这个虚根也要cost,所以最后的结果是dp[0][m+1]. 本题是cost=1的特殊背包问题,在两个for循环上有一个优化. for(f+1...j....cost) for(1....k...j-cost) 其中f为当前已经dfs子结点个数.之所以+1,是因为根要预留一个空间. f+

hdu 1561 The more, The Better (树上背包)

The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5516    Accepted Submission(s): 3280 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物

HDU 1561 The more, The Better(树形dp+背包)

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6000    Accepted Submission(s): 3548 Problem Description ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻