codeforce 382 div2 E —— 树状dp
题意:给一棵n个结点的无根树染色,求使每个结点距离为k的范围内至少有一个被染色的结点的总染色方法数目
分析:首先我们定义: 对于结点v, 如果存在一个黑色结点u距离v不超过k,则结点v被“控制”
首先将无根树转换成以1为根的有根树,设dp[v][i]为对于以v为根的子树,距离v最近的黑色结点深度为i时, 该子树中结点全部被控制或者可能在其他子树的影响下被全部控制的染色方法数。
下面来解释一下, 我们知道,当两个黑色结点距离不超过2*k+1时,其间的所有节点都被控制。那么当 i <= k 时,子树中的结点可以被全部控制, 当 k + 1 <= i <= 2*k+1 时, 子树中的节点不可能自动全被控制,但是可能在该子树根结点染色以及其他子树影响下被全部控制。
如何计算v的dp值呢,假如v只有一个儿子u, 那么 dp[v][i] = dp[u][i-1]; 如果v有多个儿子,那么首先按上述方法合并v和第一个子树,然后将子树v与其他子树合并。
那么如何合并两棵子树v, u呢?
首先考虑v的根结点为白色的状态,可以枚举(i,j)的所有情况,其中 i 是第一棵子树最近黑结点的深度(i>0),j 是第二棵子树最近黑结点的深度,如果i+j <= 2*k,则更新dp[v][min(i, j+1)], 这个状态是节点全部被控制的状态。如果i+j > 2*k, 则此状态子树中节点无法自发地全部被控制,但是可以在其他子树的影响下被全部控制。
if i+j <= 2*k , update dp[v][min(i, j+1)]
else update dp[v][max(i, j+1)]
计算完根结点为白色的情况之后,考虑根结点为黑色,那么最近距离v节点不超过2*k+1的情况数目之和就是所求,
即 dp[v][0] = ∑ dp[v][i] ( i from 1 to 2*k+1 )
比较难以理解的地方是一个子树全为白色的情况如何进行更新,其实可以这样想,对于每个叶子节点u,假想距离u节点k+1的深度有一个黑色结点,那么对于子树u,dp[u][0] = 1,这是子树完全被控制的情况, dp[u][k+1] = 1, 这是该叶子节点可能在其他子树影响下被控制的情况。这样对于所有节点都可以以上述方式更新。
ps:此题难点在于状态的设计以及状态的转移方法,需要反复琢磨。
附上代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <iostream> using namespace std;
typedef long long LL; #define M 1000000007
#define rep(i, x, n) for(int i = x; i <= (n); i++)
const int maxn = ;
const int maxk = + ; LL dp[maxn][*maxk];
LL temp[*maxk]; vector<int> G[maxn];
int n, k;
void dfs(int v, int f) {
int len = G[v].size();
if(G[v].size() == && f != ) { //处理除 1 这个根结点之外的叶子
dp[v][] = dp[v][k+] = ;
return ;
}
int flag = ;
rep(i, , len-) {
int u = G[v][i];
if(u == f) continue;
dfs(u, v);
if(!flag) {
rep(i, , *k) dp[v][i+] = dp[u][i];
flag = ;
}
else {
rep(i, , *k+) temp[i] = dp[v][i], dp[v][i] = ;
rep(i, , *k) rep(j, , *k+)
if(i+j <= *k) dp[v][min(j, i+)] = (dp[v][min(j, i+)] + temp[j]*dp[u][i]) % M;
else dp[v][max(j, i+)] = (dp[v][max(j, i+)] + temp[j]*dp[u][i]) % M;
}
}
//计算子树根结点为黑色的情况
rep(i, , *k+) dp[v][] = (dp[v][] + dp[v][i]) % M;
}
int main(){
scanf("%d%d", &n, &k);
rep(i, , n) G[i].clear();
memset(dp, , sizeof dp);
for(int i = ;i < n; i++){
int a, b;
scanf("%d%d",&a, &b);
G[a].push_back(b);
G[b].push_back(a);
}
dfs(, );
LL ans = ;
for(int i = ;i <= k; i++)
ans = (ans + dp[][i])%M;
if(!ans) ans = ;
cout << ans << endl;
return ;
}
codeforce 382 div2 E —— 树状dp的更多相关文章
- 树状DP (poj 2342)
题目:Anniversary party 题意:给出N各节点的快乐指数,以及父子关系,求最大快乐指数和(没人职员愿意跟直接上司一起玩): 思路:从底向上的树状DP: 第一种情况:第i个员工不参与,F[ ...
- poj3659树状DP
Cell Phone Network Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6273 Accepted: 225 ...
- hdu 1561 The more, The Better_树状dp
题目链接 题意:给你一棵树,各个节点都有价值(除根节点),从根节点出发,选择m个节点,问最多的价值是多小. 思路:很明显是树状dp,遍历树时背包最优价值,dp[i][k]=max{dp[i][r]+d ...
- poj 2342 Anniversary party_经典树状dp
题意:Ural大学有n个职员,1~N编号,他们有从属关系,就是说他们关系就像一棵树,父节点就是子节点的直接上司,每个职员有一个快乐指数,现在要开会,职员和职员的直接上司不能同时开会,问怎才能使开会的快 ...
- 树状DP HDU1520 Anniversary party
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1520 题意:职员之间有上下级关系,每个职员有自己的happy值,越高在派对上就越能炒热气氛.但是必须是 ...
- [Codeforces743D][luogu CF743D]Chloe and pleasant prizes[树状DP入门][毒瘤数据]
这个题的数据真的很毒瘤,身为一个交了8遍的蒟蒻的呐喊(嘤嘤嘤) 个人认为作为一个树状DP的入门题十分合适,同时建议做完这个题之后再去做一下这个题 选课 同时在这里挂一个选取节点型树形DP的状态转移方程 ...
- HDU 4714 Tree2cycle(树状DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup)
Description A tree with N nodes and N-1 edges is given. To connect or disconnect one edge, we need 1 ...
- poj2486--Apple Tree(树状dp)
Apple Tree Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 7789 Accepted: 2606 Descri ...
- 洛谷P2015 二叉苹果树(树状dp)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 我们用一根树枝两端连接的结点的编号来 ...
随机推荐
- python ndarray相关操作:重构
- JavaScript--取消a标签和form的submit提交默认行为
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- hackerrank--- challenges/fp-update-list
纯属为了练习haskell, 竟然贴代码都没办法高亮. challenges/fp-update-list Update the values of a list with their absolut ...
- PHP生成唯一的促销/优惠/折扣码,由字母和数字组成。
首先我们先搞清楚什么是促销/优惠/折扣码?它有什么用作: 每一个电子商务网站,现在有一种或多种类型的优惠/折扣/优惠券系统,给大家分享一下如何在PHP生成唯一的促销/折扣码.主要是实现一个优惠码系统, ...
- iOS 微信支付如果遇到跳转只有一个确定请看这里
http://www.cocoachina.com/bbs/read.php?tid-321546.html 今天在联调微信支付,不得不说,和它比起来,阿里的支付sdk真的是太好用了.果然和后端同学在 ...
- PLAY2.6-SCALA(七) Streaming HTTP response
1.从HTTP1.1开始,服务端为了在single connection下对HTTP请求及响应提供服务,需要在response中提供响应的Content-Length. 默认情况下,不需要显示的指明C ...
- 说说iOS与内存管理(上)
http://www.cocoachina.com/ios/20150625/12234.html 说起内存管理,看似老生常谈,而真正掌握内存管理的核心其实并不简单.ARC/MRR以及“谁分配谁就负责 ...
- This cache store does not support tagging.
用户权限管理系统 https://github.com/Zizaco/entrust 再添加角色的时候... 报了一个错.. BadMethodCallException in Repository. ...
- Vue.js 第1章 Vue常用指令学习
今日目标 能够写出第一个vue应用程序 能够接受为什么需要学vue 能够使用指令 能够通过指定完成简单的业务(增加删除查询) 能够理解mvvm 为什么要学习vue 企业需要 可以提高开发效率 实现vu ...
- Win10家庭版如何启用本地组策略
组策略对于优化和维护Windows系统来说十分重要.众所周知,Windows 10家庭版中并不包含组策略,对于使用家庭版Windows的朋友来说,十分不方便.小编将以Windows10家庭版为例,带大 ...