The more, The Better

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

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
 
这是一道经典的树形DP,去年去凤凰之前就碰到过这道题目了。但是没有看懂思路。
额额,居然拖到现在.
 
思路:
     一看就感觉是背包,还加上了限定个数的条件 M 。
     而且,存在依赖关系。装子节点的前提是,把其父亲节点也要装进去才行。
    
     这样的情况,感觉挺难的。
1.   dp[ k ][ j ] 代表  对于 k 节点,收集了 j 个 其子节点的最大价值。
     是否,要采取对 叶子节点  和 非叶子节点 来进行分类讨论呢?
     不是的,更加题意的依赖关系。
     我们能得到一个共性的初始化。
     dp[ k ][ 0 ]=0;
     dp[ k ][ 1 ]=val[k];//这个是要的,只有把自己装进去了,才能装你子节点呀。
   递推公式: 
   dp[ k ][ j ] = max(  dp[ k ][ j ] , dp[ dp[k].next[i] ][ j-x ] + dp[ k ][ x ] );
 
     dp[ dp[k].next[i] ][ j-x ] 表示在 k 节点 的 某个子节点里 收集 j-x 个节点。
     dp[ k ][ x ]               表示在 k 节点 里 收集 x 个节点。
 
 
2.   寻找根节点,我们发现,有许多的森林。那么我用0来做根节点。自然 m++;        
   
3.   最后一个问题是如何书写这个背包了。
     for( i=1; i<= f[k].num; i++)//枚举多有少的节点。
    {
        t=f[k].next[i];
        dfs(t); //搜索,实现递归。
              for(j=m;j>=2;j--)// 不会表达。囧... 枚举该节点能收集的个数。
          {
              for(s=1;s<=j;s++)//枚举其该儿子节点 t 收集的个数。
                {
                  dp[k][j]=Max(dp[k][j],dp[t][j-s]+dp[k][s]);
                }
          }
      }
 
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int n,m;
struct node
{
int next[];
int num;
}f[];
int dp[][]; int Max(int x,int y)
{
return x>y? x:y;
} void dfs(int k)
{
int i,j,t,s;
dp[k][]=;
for(i=;i<=f[k].num;i++)//枚举每一个点
{
t=f[k].next[i];
dfs(t);
for(j=m;j>=;j--)//枚举
{
for(s=;s<=j;s++)
{
dp[k][j]=Max(dp[k][j],dp[t][j-s]+dp[k][s]);
}
}
}
} int main()
{
int i,x;
while(scanf("%d%d",&n,&m)>)
{
if(n==&&m==)break; memset(dp,,sizeof(dp));
for(i=;i<=;i++) f[i].num=; for(i=;i<=n;i++)
{
scanf("%d%d",&x,&dp[i][]);
f[x].num++;
f[x].next[f[x].num]=i;
}
m++;
dfs();
printf("%d\n",dp[][m]);
}
return ;
}

/*
如何保证 子节点 装进去的前提是父亲节点被装进去了。
是更具dp[i][1]=val[i];

在推导的过程中,虽然刚开始容量为m的每个格子不是都有val[i]的值。
但是放入多少个,例如n,那么对于在容量为n的格子里,就一定会有val[i]的存在

*/

 

HDU 1561 The more, The Better 经典树形DP的更多相关文章

  1. HDU 1561 The more, The Better【树形DP/有依赖的分组背包】

    ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物.但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先 ...

  2. HDU 1561 The more, The Better(树形dp之树形01背包)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1561 The more, The Better Time Limit: 6000/2000 MS (J ...

  3. HDU 1561 The more, The Better(树形DP+01背包)

    The more, The Better Time Limit : 6000/2000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other ...

  4. HDU 1561 The more, The Better (树形DP,常规)

    题意:给一个森林,n个节点,每个点有点权,问若从中刚好选择m个点(选择某点之前必须先选择了其父亲),使得这m个点权之和最大为多少? 思路: 比较常规.就是DFS一次,枚举在子树中可能选择的k个点(注意 ...

  5. HDU 1561 The more, The Better(树形背包)

    The more, The Better Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  6. hdu 1520 Anniversary party(第一道树形dp)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1520 Anniversary party Time Limit: 2000/1000 MS (Java ...

  7. HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4126 Genghis Khan the Conqueror Time Limit: 10000/50 ...

  8. hdu 5909 Tree Cutting——点分治(树形DP转为序列DP)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5909 点分治的话,每次要做一次树形DP:但时间应该是 siz*m2 的.可以用 FWT 变成 siz*ml ...

  9. bzoj 2159 Crash 的文明世界 && hdu 4625 JZPTREE ——第二类斯特林数+树形DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2159 学习材料:https://blog.csdn.net/litble/article/d ...

随机推荐

  1. jvisualvm_使用jstatd连接远程linux应用

    [1]确定linux系统正确安装了ssh # sudo ps -e | grep ssh ①注意使用root,使用$会报如下错误: [appadmin@webcsuat2 ~]$ sudo ps -e ...

  2. luoguP3359 改造异或树

    https://www.luogu.org/problemnew/show/P3359 因为 a ^ b ^ b = a,所以我们预处理 1 到所有点的距离,将删边的操作反过来变成加边,对于每一个联通 ...

  3. [ActionScript 3.0] AS3 ServerSocket示例(官方示例)

    下面的示例创建一个套接字服务器.要使用该服务器,可将套接字绑定到本地端口,然后从其他应用程序连接到该端口.该服务器仅识别 UTF-8 字符串. package { import flash.displ ...

  4. ajax跨域请求问题

    ajax是不允许跨域请求的,今天在使用bootstap-table的时候,data-url使用的地址是绝对地址,而非相对地址,因此在载入数据的时候就出错了. 启动的时候使用是 http://127.0 ...

  5. C#找出接口的所有实现类并遍历执行这些类的公共方法

    //这里找出了实现IOutputArray接口的所有类 private void FindAllClass() { var types = AppDomain.CurrentDomain.GetAss ...

  6. Saiku2.6 Saiku315 链接SQL的JDBC字符串

    Saiku26 type=OLAP name=CloudConn driver=mondrian.olap4j.MondrianOlap4jDriver location=jdbc:mondrian: ...

  7. elasticsearch kibana简单查询

    kibana CRUD 操作页面 一.简单的CRUD操作 1.添加 PUT /index/type/id {  "json数据" } 2.查询 GET /index/type/id ...

  8. HDU - 5306 剪枝的线段树

    题意:给定\(a[1...n]\),\(m\)次操作,0表示使\([L,R]\)中的值\(a[i]=min(a[i],x)\),其余的1是查最值2是查区间和 本题是吉利爷的2016论文题,1 2套路不 ...

  9. linux系统管理(1)之 内核编译选项查看

    三个方法 proc文件系统 ubunut debain 红帽等 proc文件系统 /proc/config.gz This file shows you the compile-time config ...

  10. 关于DES加密内部收费版

    数据加密算法(Data Encryption Algorithm,DEA)是一种对称加密算法,很可能是使用最广泛的密钥系统,特别是在保护金融数据的安全中,最初开发的DEA是嵌入硬件中的.通常,自动取款 ...