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: FFmpeg编译和使用 学习
ffmpeg是一个多平台多媒体处理工具,处理视频和音频的功能非常强大.目前在网上搜到的iOS上使用FFMPEG的资料都比较陈旧,而FFMPEG更新迭代比较快: 且网上的讲解不够详细,对于初次接触FFM ...
- iOS 控制器的跳转、页面四个方向的跳转
指定滑动方向的跳转 CATransition *transition = [CATransition animation]; transition.duration = 0.3f; transitio ...
- Kafka+Storm写入Hbase和HDFS
1.Storm整合Kafka 使用Kafka作为数据源,起到缓冲的作用 // 配置Kafka订阅的Topic,以及zookeeper中数据节点目录和名字 String zks = KafkaPrope ...
- [数据结构]C语言链表实现
我学数据结构的时候也是感觉很困难,当我学完后我发现了之所以困难时因为我没有系统的进行学习,而且很多教授都只是注重数据结构思想,而忽略了代码方面,为此我写了这些博文给那些试图自学数据结构的朋友,希望你们 ...
- 从头开始搭建一个Spring boot+ActiveMQ高可用分布式环境
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- DNS查询相关
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/45 一种简单的设计方式是在因特网上使用一个DNS服务器,该服务器 ...
- OpenStack运维(四):OpenStack备份恢复
1.备份注意事项 要保留多少备份? 是否需要异地备份? 备份间隔多久? 恢复策略? 2.备份什么 2.1 数据库备份 2.1.1 制定crond 每天备份一次 2.1.2 备份命令根据系统而定,可用 ...
- 5.Nginx作为web缓存服务器
Nginx作为web缓存服务器 从0.7.48版本开始,Nginx支持类似Squid的缓存功能.Nginx的web缓存服务主要由proxy_cache相关命令集合fastcgi_cache相关命令集构 ...
- python内置函数与匿名函数
内置函数 Built-in Functions abs() dict() help() min() setattr() all() dir() hex() next() slice() any() d ...
- tornado返回指定的http code
最近做web api,需要在接口返回异常时,返回对应的http code. 查了下tornado的文档,是通过set_status方法来设置返回的http code,做个记录. self.set_st ...