The more, The Better

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

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
 
 
 
当可以直接攻克城堡i时,我们认为先要攻克城堡0,才可以选择去攻克城堡i
则这道题的图就变成了一棵有根树,root=0
 
我们发现,这道题和POJ1155是差不多的,区别在于:
1155我们只把叶子节点看成是背包
而这道题,我们把每一个节点都看成是一个背包
 
既然是背包,那么现在就是要拿哪些背包(节点)的问题了。
 
dp[i][j] 表示以节点i为根的子树中,拿j个背包的最大收益
dp初始化为-inf
 
则我们要拿节点v,则必须拿节点father(v)
则肯定有:
dp[i][0]=0
dp[i][1]=cost[i]
dp[i][j>1]时,必须拿节点i这一个背包,剩下的j-1个背包再从节点i的儿子节点所在的子树中拿
那么递推式就出来了
j-k>=1时,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[son][k])
(j-k>=1保证了当前子树根节点i这个背包一定会被拿到)
 
注意递推时候j,k的递推顺序
 
 
 #include<cstdio>
#include<cstring> using namespace std; inline int max(int a,int b)
{
return a>b?a:b;
} const int maxn=;
const int inf=0x3f3f3f3f; int dp[maxn][maxn];
int cost[maxn];
int siz[maxn];
int out[maxn];
struct Edge
{
int to,next;
};
Edge edge[maxn];
int head[maxn];
int tot; void addedge(int u,int v)
{
edge[tot].to=v;
edge[tot].next=head[u];
head[u]=tot++;
} void init(int n)
{
memset(head,-,sizeof head);
tot=;
memset(out,,sizeof out);
for(int i=;i<=n;i++)
{
dp[i][]=;
for(int j=;j<=n;j++)
dp[i][j]=-inf;
}
} void solve(int ,int );
void dfs(int ); int main()
{
int n,m;
while(~scanf("%d %d",&n,&m))
{
if(!n&&!m)
break;
init(n);
cost[]=;
for(int i=;i<=n;i++)
{
int u;
scanf("%d %d",&u,&cost[i]);
addedge(u,i);
out[u]++;
}
solve(n,m);
}
return ;
} void solve(int n,int m)
{
dfs();
printf("%d\n",dp[][m+]);
return ;
} void dfs(int u)
{
siz[u]=;
for(int i=head[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(!out[v])
{
dp[v][]=;
dp[v][]=cost[v];
siz[v]=;
}
else
{
dfs(v);
}
siz[u]+=siz[v];
dp[u][]=cost[u];
for(int j=siz[u];j>=;j--)
{
for(int k=;k<=siz[v];k++)
if(j-k>=)
dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
}
}
}
 
 
 
 
 

hdu 1561 The more, The Better 背包型树形DP 简单题的更多相关文章

  1. POJ 1155 TELE 背包型树形DP 经典题

    由电视台,中转站,和用户的电视组成的体系刚好是一棵树 n个节点,编号分别为1~n,1是电视台中心,2~n-m是中转站,n-m+1~n是用户,1为root 现在节点1准备转播一场比赛,已知从一个节点传送 ...

  2. HDU 1520 树形dp裸题

    1.HDU 1520  Anniversary party 2.总结:第一道树形dp,有点纠结 题意:公司聚会,员工与直接上司不能同时来,求最大权值和 #include<iostream> ...

  3. POJ 2342 &&HDU 1520 Anniversary party 树形DP 水题

    一个公司的职员是分级制度的,所有员工刚好是一个树形结构,现在公司要举办一个聚会,邀请部分职员来参加. 要求: 1.为了聚会有趣,若邀请了一个职员,则该职员的直接上级(即父节点)和直接下级(即儿子节点) ...

  4. HDU 4616 Game (搜索)、(树形dp)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4616 这道题目数据可能比较弱,搜索都可以AC,但是不敢写,哎…… 搜索AC代码: #include & ...

  5. HDU - 1054 Strategic Game(二分图最小点覆盖/树形dp)

    d.一颗树,选最少的点覆盖所有边 s. 1.可以转成二分图的最小点覆盖来做.不过转换后要把匹配数除以2,这个待细看. 2.也可以用树形dp c.匈牙利算法(邻接表,用vector实现): /* 用ST ...

  6. HDU 2196 Computer 树形DP经典题

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=2196 题意:每一个电脑都用线连接到了还有一台电脑,连接用的线有一定的长度,最后把全部电脑连成了一棵树,问 ...

  7. 【HDU 4276】The Ghost Blows Light(树形DP,依赖背包)

    The Ghost Blows Light Problem Description My name is Hu Bayi, robing an ancient tomb in Tibet. The t ...

  8. hdu 4044 2011北京赛区网络赛E 树形dp ****

    专题训练 #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm ...

  9. hdu 2196 Computer 树形dp模板题

    Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

随机推荐

  1. Gym 100285G Cipher Message 3

    题意 给\(N,M(N,M \le 250000)\)的两个由8位二进制表示的两个序列,允许改变每个数字的第8位的数值(即0→1,1→0),求改变最少次数使得长为\(M\)的序列为长为\(N\)的连续 ...

  2. Linux驱动设计—— 内核模块(一)

    Linux内核理论基础 组成Linux内核的5个子系统:进程调度(SCHED)/内存管理(MM)/虚拟文件系统(VFS)/网络接口(NET)/进程间通信(IPC). 进程调度(SCHED) 在设备驱动 ...

  3. 为什么你应该试试用Sublog写博客

    HI 这篇文章发布后,收到了一些反馈,在不同的阅读媒体上(浏览器,RSS,evernote)等,会有样式兼容问题,特别是之前的代码显示行号的实现方式,使用浮动code块,兼容问题比较严重,所以做了一个 ...

  4. linux服务之vnc和x2go

    三种方式连接linux桌面 1.传统的vnc linux桌面上安装vncserver windows桌面上安装vncviewer 2.x2go 在linux桌面上安装x2goserver与x2gose ...

  5. 自己理解的javascript 的对象和类理解

    首先需要先理解类和对象的意义,我个人理解如下: 类:对象的抽象化: 对象:类的实体: javascript中没有class关键字和类的用法,只能用伪类来做类的,所以要用function来定义累的名字: ...

  6. WCF学习心得----(四)服务承载

    WCF学习心得----(四)服务承载 这一章节花费了好长的时间才整理个大概,主要原因是初次接触这个东西,在做练习实践的过程中,遇到了很多的问题,有些问题到目前还没有得以解决.所以在这一章节中,有一个承 ...

  7. 【linux】压缩和解压缩

    .gz格式 压缩gzip: gzip只能压缩文件,且压缩后文件消失,不能压缩目录. [root@andon tmp]# ls ml orbit-gdm pulse-2sLvu7UbjUYf pulse ...

  8. HackerRank "Dorsey Thief"

    A variation to 0-1 Knapsack. (No Python code got fully AC. Python is too slow for this problem) #inc ...

  9. windows下 更新 android studio SDK 到最新版本 解决方案

    一.设置代理信息 打开android studio>>File>>Settings>>Appearance&Behavion>>System S ...

  10. IntelliJ IDEA自动去掉行尾空格

    Settings→Editor→General 先选中Allow placement of caret after end of line 再修改Strip trailing spaces on Sa ...