hdu_1011(Starship Troopers) 树形dp
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1011
题意:打洞洞收集脑子,你带领一个军队,洞洞互联成一棵树,每个洞中有一些bug,要全部杀死这些虫子才可以取得这个洞中的脑子,只有杀死当前节点的bug才可以继续走下去,且如果有0个bug你仍要派遣一个士兵在这里,只不过可以士兵不停留。
题解:很清晰明了的树形dp了,但是某些人说过写题解就要写细致。。。所以我们还是来详细讲解一下树形dp吧。。。
树形dp:
这是一个很裸的树形dp,和一般的dp不同的是,树形dp有了分支,所以要考虑子孩子和父亲孩子之间的关系。及父亲的最大值来源于其自孩子反馈给他的结果。
我们考虑dp[i][j]表示当前以第i个节点为编号的已经考虑的子树种耗费j个士兵的情况可以获得的最大收益
(分析的时候自顶向下,实现自底向上,这也是dfs的思想,树形dp一般都是在dfs过程中实现的)
考虑如果我们知道了当前节点所有子孩子的dp值,即我们知道了给当前已经考虑的孩子分着多少个士兵可以获得他和子孩子的最大收益,那么再考虑他的下一个子孩子的时候
就可以在此基础上枚举将士兵挨个分给新的子孩子的时候的最大收益,最后我们考虑完所有的子孩子,并把所有士兵都分下去就是结果了。
给出dp方程: dp[i][j] = max(dp[i][j],dp[i][j-k]+dp[son][k]);
画个图来帮助理解一下:

是不是很简单腻~图上没有说一些细节,和一般的dp一样,要考虑之前计算的点是否会被覆盖问题,在枚举j时候要从m向前搜索,因为如果从后往前,计算后面dp[i][j]的时候用到dp[i][j-k]已经被修改过了。还有一个细节就是如何保证当前节点有没有bug都分给一个士兵,这个很简单,只要k从1开始循环就可以了,即保证了无论怎样都给这个节点一个士兵。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = ;
int n,m;
int cost[N],value[N];
int vis[N];
struct Edge{
int to;
int next;
}edge[N*N];
int Ecnt;
int head[N];
int dp[N][N];
void init()
{
for(int i = ; i <= n; i++ ){
head[i] = -;
vis[i] = ;
}
Ecnt = ;
memset(dp,,sizeof(dp));
}
void add(int from, int to)
{
edge[Ecnt].to = to;
edge[Ecnt].next = head[from];
head[from] = Ecnt++; edge[Ecnt].to = from;
edge[Ecnt].next = head[to];
head[to] = Ecnt++;
}
void dfs(int id)
{
vis[id] = ;
int tm;
if(m<cost[id]) return;
for(int j = cost[id]; j <= m; j++) dp[id][j] = value[id];
for(int d = head[id]; d!=-; d = edge[d].next)
{
tm = edge[d].to;
if(!vis[tm]){
dfs(tm);
for(int j = m; j >= cost[id]; j--){
for(int k = ; k <= (j-cost[id]); k++){
if(j-k>=cost[id])
dp[id][j] = max(dp[id][j],dp[id][j-k]+dp[tm][k]);
}
}
}
}
return;
}
int main()
{
int tm,tm1,tm2;
while(~scanf("%d%d",&n,&m))
{
if(n==-&&m==-) return ;
for(int i = ; i <= n; i++)
{
scanf("%d %d",&tm,&value[i]);
cost[i] = (tm+)/;
}
init();
for(int i = ; i < n; i++)
{
scanf("%d %d",&tm1,&tm2);
add(tm1,tm2);
}
vis[] = ;
if(m==){printf("0\n");continue;}
dfs();
printf("%d\n",dp[][m]);
}
return ;
}
hdu_1011(Starship Troopers) 树形dp的更多相关文章
- hdu 1011 Starship Troopers(树形DP入门)
Starship Troopers Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDU 1011 Starship Troopers 树形DP 有坑点
本来是一道很水的树形DP题 设dp[i][j]表示,带着j个人去攻打以节点i为根的子树的最大收益 结果wa了一整晚 原因: 坑点1: 即使这个节点里面没有守卫,你如果想获得这个节点的收益,你还是必须派 ...
- hdu1011 Starship Troopers 树形DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 思路:很明显的树形背包 定义dp[root][m]表示以root为根,派m个士兵的最优解,那么d ...
- [HDU 1011] Starship Troopers (树形dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 dp[u][i]为以u为根节点的,花了不超过i元钱能够得到的最大价值 因为题目里说要访问子节点必 ...
- hdu 1011 Starship Troopers 树形背包dp
Starship Troopers Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- hdu 1011 Starship Troopers(树形背包)
Starship Troopers Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- HDU 1011 Starship Troopers 树形+背包dp
http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意:每个节点有两个值bug和brain,当清扫该节点的所有bug时就得到brain值,只有当父节点被 ...
- hdu_1011_Starship Troopers(树形DP)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意:有N个房间,房间的连通性为树形的,就是说你要占领子结点,必须要先占领 父结点,每个房间有第 ...
- HDU 1011 Starship Troopers (树dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意: 题目大意是有n个房间组成一棵树,你有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个 ...
随机推荐
- iOS 数据加密方案
iOS安全攻防(二十三):Objective-C代码混淆 提交用户的隐私数据 一定要使用POST请求提交用户的隐私数据GET请求的所有参数都直接暴露在URL中请求的URL一般会记录在服务器的访问日志中 ...
- oracle初级(续)
有志者.事竟成,破釜沉舟,百二秦关终属楚: 苦心人.天不负,卧薪尝胆,三千越甲可吞吴. oracle基本简单的用法,之前的笔记稍作整理一下,希望对各位有用,如有问题可在下方留言,所有SQL都是经过or ...
- C#生成缩略图 (通用模式)
用数据库保存图片的路径和文件名称,把文件保存在文件夹中.//保存在数据库中的文件路径ArrayList arrFilePath=new ArrayList();arrFilePath=myCommon ...
- linux下新建svn项目
1.新建项目svnadmin create /mnt/fbdisk/svn/newproject 2.会在svn下面建立newproject目录total 24drwxr-xr-x 2 root ro ...
- 当你的电脑出现stop: 0X0000007B
这几天可算是把我折腾惨了.先是linux系统无法进入图形化桌面,几经折腾,我把linux删除重装.怎知道,我在瘟都死下删除linux的分区,结果我的两个瘟都死分区也没了,哭了我去恢复数据,但是然并卵. ...
- JavaScript的DOM编程--05--获取文本节点
获取文本节点: 1). 步骤: 元素节点 --> 获取元素节点的子节点 2). 若元素节点只有文本节点一个子节点, 例如 <li id="bj" name=" ...
- Linux如何让进程在后台运行的三种方法详解
问题分析: 我们知道,当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程.因此,我们的解决办法就有两种途径:要么让进程忽略 HUP 信号,要么让进程运 ...
- Pyhon学习_04_字典、集合
字典.集合两种基本类型都是通过映射的方式访问. 字典 python中的字典和perl中的哈希是很相似的,包括其重要的几条属性: 1. 键值必须是唯一的 2. 键值必须是可哈希的,也就是键值不能够是可变 ...
- 让git不再跟踪配置文件的变化
我们经常会在配置文件里留下一些敏感信息 比如数据库链接字符串的用户名和密码 如果不提交配置文件到github或者其他源码管理网站 那么你的粉丝很可能就无法正确运行你的项目,就达不到开源的目的了 那么, ...
- 实战经验分享之C#对象XML序列化
.Net Framework提供了对应的System.Xml.Seriazliation.XmlSerializer负责把对象序列化到XML,和从XML中反序列化为对象.Serializer的使用比较 ...