【学时总结】◆学时·VIII◆ 树形DP
◆学时·VIII◆ 树形DP
DP像猴子一样爬上了树……QwQ
◇ 算法概述
基于树的模型,由于树上没有环,满足DP的无后效性,可以充分发挥其强大统计以及计算答案的能力。
一般来说树形DP的状态定义有三种:偏简单的,dp[u]表示以u为根的子树的最优解/方案数;带选择性质的:dp[u][0/1],表示以u为根的子树中选择/不选择u的最优解/方案数;dp[u][i] 表示以u为根的子树中,u的状态为i的最优解/方案数(其实就是第二种定义的扩展)。
一般来说题目给的是一个树形图,那么我们只需要从图中一个存在的节点开始DP即可。注意向下DP时不要重复访问父节点。
由于树这种结构中,儿子与父亲的关系比较紧密,我们一般采用记忆化搜索,可以减免大量不合法的计算(只有儿子与父亲之间才能直接计算)。
◇ 经典选讲
(均出自《算法竞赛入门经典》-刘汝佳)
【UVa 12186】Another Crisis(工人的请愿书)
<题意>
某公司里有一个老板和n(n≤10 5 )个员工组成树状结构,除了老板之外每个员工都有唯一的直属上司。老板的编号为0,员工编号为1~n。工人们(即没有直接下属的员工)打算签署一项请愿书递给老板,但是不能跨级递,只能递给直属上司。当一个中级员工(不是工人的员工)的直属下属中不小于T%的人签字时,他也会签字并且递给他的直属上司。问:要让公司老板收到请愿书,至少需要多少个工人签字?
<解析>
这道题实质上是给定了一个以老板为根的有根树,于是我们DP的起点便是老板。定义状态为dp[u]为员工u签字最少需要多少个人签字。
对于工人u(没有直接下属),能够直接提供一个签字,即dp[u]=1,仅需要一人签字。对于其他非工人员工v,我们计算出他的每一个直属下属的dp值,存入cnt;再通过题目提供的百分数,算出要让他签字,他的直属下属员工最少有多少个需要签字,记为Maxi;那么要让v签字,最少要签字的人数为cnt中前Maxi个最小的值之和。
因为我们要使答案尽量小,取前Maxi个最小的值就可以达到目的。
(详见代码,如果有一些没懂的可以在邮箱里询问~)
<源代码>
/*Lucky_Glass*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int MAXN=int(1e5);
vector<int> lnk[MAXN+];
int n,m;
int dp[MAXN+];
inline bool cmp(int A,int B){return dp[A]<dp[B];}
int DP(int u){
if(dp[u]) return dp[u];
if(lnk[u].size()==) return dp[u]=;
vector<int> cnt;
for(int i=;i<(int)lnk[u].size();i++)
cnt.push_back(DP(lnk[u][i]));
sort(cnt.begin(),cnt.end());
int Maxi=lnk[u].size()*m/+(lnk[u].size()*m%? :);
for(int i=;i<Maxi;i++)
dp[u]+=cnt[i];
return dp[u];
}
int main(){
//freopen("in.txt","r",stdin);
while(~scanf("%d%d",&n,&m) && n && m)
{
memset(dp,,sizeof dp);
memset(lnk,,sizeof lnk);
for(int i=,pre;i<=n;i++)
scanf("%d",&pre),lnk[pre].push_back(i);
printf("%d\n",DP());
}
return ;
}
Another Crisis
【UVa 1220】Party at Hali-Bula(Hali-Bula的晚会)
<题意>
公司里有n(n≤200)个人形成一个树状结构,即除了老板之外每个员工都有唯一的直属上司。要求选尽量多的人,但不能同时选择一个人和他的直属上司。问:最多能选多少人,以及在人数最多的前提下方案是否唯一。输出第一个数为最多能选多少人,接下来若仅有一种选择方案能够达到最大选择人数,则输出Yes,否则输出No。
<解析>
本题相对上一题又多了一层状态——当前节点选或不选。也就是最开始在算法概述中描述的第二种状态定义。
先处理输入,我们先利用STL容器map<string,int>将名字映射到编号上,相当于重新编了号,固定“老板”的编号为1。
根据题意可知,对于一棵子树,若选取其根节点,则根节点的所有儿子都不能选;若不选根节点,则根节点的儿子可选可不选。那么我们DP开始时就要先判断“老板”这个节点选还是不选,即在dp[1][0]和dp[1][1]中取较大值。那么可以得到下面的状态转移方程式:
应该还是很好理解吧
【学时总结】◆学时·VIII◆ 树形DP的更多相关文章
- poj3417 LCA + 树形dp
Network Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4478 Accepted: 1292 Descripti ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 【BZOJ-4726】Sabota? 树形DP
4726: [POI2017]Sabota? Time Limit: 20 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 128 Solved ...
- 树形DP+DFS序+树状数组 HDOJ 5293 Tree chain problem(树链问题)
题目链接 题意: 有n个点的一棵树.其中树上有m条已知的链,每条链有一个权值.从中选出任意个不相交的链使得链的权值和最大. 思路: 树形DP.设dp[i]表示i的子树下的最优权值和,sum[i]表示不 ...
- 树形DP
切题ing!!!!! HDU 2196 Anniversary party 经典树形DP,以前写的太搓了,终于学会简单写法了.... #include <iostream> #inclu ...
- BZOJ 2286 消耗战 (虚树+树形DP)
给出一个n节点的无向树,每条边都有一个边权,给出m个询问,每个询问询问ki个点,问切掉一些边后使得这些顶点无法与顶点1连接.最少的边权和是多少.(n<=250000,sigma(ki)<= ...
- POJ2342 树形dp
原题:http://poj.org/problem?id=2342 树形dp入门题. 我们让dp[i][0]表示第i个人不去,dp[i][1]表示第i个人去 ,根据题意我们可以很容易的得到如下递推公式 ...
- hdu1561 The more, The Better (树形dp+背包)
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1561 思路:树形dp+01背包 //看注释可以懂 用vector建树更简单. 代码: #i ...
- bzoj2500: 幸福的道路(树形dp+单调队列)
好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...
随机推荐
- pat1091. Acute Stroke (30)
1091. Acute Stroke (30) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue One impo ...
- GET 和 POST详解
什么是 HTTP? 超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信. HTTP 的工作方式是客户机与服务器之间的请求-应答协议. web 浏览器可能是客户端,而计算机上的网络应用程 ...
- SEO--HTML meta标签总结
<!DOCTYPE html> <!-- 使用html5 doctype,不区分大小写--> <html lang="zh-CN"> <h ...
- GDI+图形图像处理技术——GDIPlus绘图基础
GDI+概述 GDI在windows中定义为Graphis Device interface,及图形设备接口,是Windows API(application Programming Interfac ...
- 阿里云短信验证~JAVA后台
maven :中的 pom.xml添加 <dependency> <groupId>com.aliyun</groupId> <artifactId>a ...
- 微信小程序电商实战-首页(下)
好了,上一期我们把首页搜索.导航栏和广告轮播给做完了,那么接下来会继续完成我们首页的剩余部分,先看我们要实现的效果吧! 本期实现效果图.gif 本期我们要实现首页的实时热销榜.福利专场和左下方个人 ...
- 秒懂JSON.parse()与JSON.stringify()的区别
在网站开发中,Json是最为常见的一种数据交互手段.在使用过程中,常会遇到Json字段串和对象之间进行转换.很多朋友对于JSON.parse() 和JSON.stringify() 的区别,下面为大家 ...
- 对react vd 性能的理解
相信大家都知道react vd的性能是很好的,速度挺快的,真实dom操作很慢的,但是结果完全相反: 后来我就做了个测试,从两个方面去测试,在页面初始渲染1w条数据,react渲染耗时超过了1秒 在12 ...
- vos设置禁止被叫特定号码段特定区域
问题: 为了防止卡线遭投诉被运营商停,给公司带来损失,对一些特定号段特定区域要进行限制,不让客户呼出 打开VOS3000 落地网关——补充设置——落地被叫前缀——禁止 添加禁止号段 具体案例: 如填写 ...
- IOS开发入门你们准备好了吗?
我们对于IOS的了解最多应该就是苹果手机独有的IOS系统吧,也可以说是单任务管理器,这可以说是一个优势,但是随着技术提升IOS慢慢有被超越的趋势,但是很多大公司还是需要这方面的开发人才,那么今天我们来 ...