题目连接: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的更多相关文章

  1. hdu 1011 Starship Troopers(树形DP入门)

    Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. HDU 1011 Starship Troopers 树形DP 有坑点

    本来是一道很水的树形DP题 设dp[i][j]表示,带着j个人去攻打以节点i为根的子树的最大收益 结果wa了一整晚 原因: 坑点1: 即使这个节点里面没有守卫,你如果想获得这个节点的收益,你还是必须派 ...

  3. hdu1011 Starship Troopers 树形DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 思路:很明显的树形背包 定义dp[root][m]表示以root为根,派m个士兵的最优解,那么d ...

  4. [HDU 1011] Starship Troopers (树形dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 dp[u][i]为以u为根节点的,花了不超过i元钱能够得到的最大价值 因为题目里说要访问子节点必 ...

  5. hdu 1011 Starship Troopers 树形背包dp

    Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  6. hdu 1011 Starship Troopers(树形背包)

    Starship Troopers Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  7. HDU 1011 Starship Troopers 树形+背包dp

    http://acm.hdu.edu.cn/showproblem.php?pid=1011   题意:每个节点有两个值bug和brain,当清扫该节点的所有bug时就得到brain值,只有当父节点被 ...

  8. hdu_1011_Starship Troopers(树形DP)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意:有N个房间,房间的连通性为树形的,就是说你要占领子结点,必须要先占领 父结点,每个房间有第 ...

  9. HDU 1011 Starship Troopers (树dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011 题意: 题目大意是有n个房间组成一棵树,你有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个 ...

随机推荐

  1. 通过 JS 判断页面是否有滚动条的简单方法

    前言 最近在写插件的过程中,需要使用 JS 判断是否有滚动条,搜了一下,大致方法都差不多,但都有些啰嗦,代码不够简洁.最终通过参考不同方法,写了一个比较简单的方法.在判断滚动条的同时也需要计算滚动条的 ...

  2. [C/C++语言标准] ISO C99/ ISO C11/ ISO C++11/ ISO C++14 Downloads

    语言法典,C/C++社区人手一份,技术讨(hu)论(peng)必备 ISO IEC C99 https://files.cnblogs.com/files/racaljk/ISO_C99.pdf IS ...

  3. 506. Relative Ranks

    Given scores of N athletes, find their relative ranks and the people with the top three highest scor ...

  4. 程序员的自我救赎---11.1:RPC接口使用规范

    <前言> (一) Winner2.0 框架基础分析 (二)PLSQL报表系统 (三)SSO单点登录 (四) 短信中心与消息中心 (五)钱包系统 (六)GPU支付中心 (七)权限系统 (八) ...

  5. bzoj 2565: 最长双回文串

    Description 顺序和逆序读起来完全一样的串叫做回文串.比如acbca是回文串,而abc不是(abc的顺序为"abc",逆序为"cba",不相同).输入 ...

  6. lesson - 15 Linux系统日常管理4

    内容概要:1. rsync 命令格式rsync [OPTION]... SRC  DESTrsync [OPTION]... SRC  [USER@]HOST:DESTrsync [OPTION].. ...

  7. cut 命令详解

    cut  作用:按列提取文件 参数: -d 指明列分隔符 -f 选择输出的区域 -c 指定字符位置 -b :以字节为单位进行分割.这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志. -c : ...

  8. VS2010安装OpenGL

     以下涉及到的所有资源都在这里: 链接:https://pan.baidu.com/s/1eSctT5K 密码:174s *我的VS2010的安装位置:D:\Program Files (x86)\M ...

  9. Zabbix 单位换算

    直接举一例子,然后再举一反三: 如图: 单位B 则基数为1024(倍数) 我性能参数为KB单位,我们则把单位转换成和我们计数器 保持一致的单位即可,一致后,zabbix 后面会自己准换成自己想要的显示 ...

  10. Yii 框架学习--03 多应用多模块

    本文以YII 2.0.7为例. 概述 首先看看多应用和多模块的特点: 多应用的特点: 独立配置文件 独立域名 多模块的特点: 统一配置文件 统一域名 那么,实际该怎么决定使用多应用还是多模块呢? 对于 ...