Codeforces 735E 树形DP
题意:给你一棵树,你需要在这棵树上选择一些点染成黑色,要求染色之后树中任意节点到离它最近的黑色节点的距离不超过m,问满足这种条件的染色方案有多少种?
思路:设dp[x][i]为以x为根的子树中,离x点最近的点的距离是i,并且满足题目中的限制条件的方案数。我们假设已经计算了x的一些子树对x的贡献,我们考虑x的一个还没产生贡献的子树y对x的贡献。用数组f作为临时变量。我们枚举x的距离i和y的距离j,容易发现有两种情况:i + j + 1 <= 2 * m + 1,这种时候不会出现不符合题目条件的点,直接转移即可:f[min(i, j + 1)] += dp[x][i] * dp[y][j]。第二种情况:i + j + 1 > 2 *m + 1, 那么就不能直接转移了,因为如果转移了会出现不符合题目中的条件的点。但是我们可以保存这两者中的最大值,作为最远点来看他们仍然是合法的,而且它们仍有可能和后面的子树形成新的答案。有一个细节需要注意一下:在处理第一棵子树的时候,我们把dp[x][0]和dp[x][m + 1]设置为0,第一个的原因是因为子树和根节点本身可以形成合法情况。第二种操作相当于取了个巧,本质是把dp[v][i]赋值给dp[x][i + 1]。
代码:
#include <bits/stdc++.h>
#define LL long long
#define INF 0x3f3f3f3f
#define db double
#define pii pair<int, int>
using namespace std;
const LL mod = 1e9 + 7;
const int maxn = 210;
LL dp[maxn][maxn], f[maxn];
vector<int> G[maxn];
int n, m;
void add(int x, int y) {
G[x].push_back(y);
G[y].push_back(x);
}
void dfs(int x, int fa) {
dp[x][0] = dp[x][m + 1] = 1;
for (auto y : G[x]) {
if(y == fa) continue;
dfs(y, x);
memset(f, 0, sizeof(f));
for (int i = 0; i <= 2 * m + 1; i++) {
for (int j = 0; j <= 2 * m; j++) {
if(i + j <= 2 * m) {
int p = min(i, j + 1);
f[p] = (f[p] + (dp[x][i] * dp[y][j]) % mod) % mod;
}
else {
int p = max(i, j + 1);
f[p] = (f[p] + (dp[x][i] * dp[y][j]) % mod) % mod;
}
}
}
for (int i = 0; i <= 2 * m; i++) {
dp[x][i] = f[i];
}
}
}
int main() {
int x, y;
scanf("%d%d", &n, &m);
for (int i = 1; i < n; i++) {
scanf("%d%d", &x, &y);
add(x, y);
}
dfs(1, -1);
LL ans = 0;
for (int i = 0; i <= m; i++) {
ans = (ans + dp[1][i]) % mod;
}
printf("%lld\n", ans);
}
Codeforces 735E 树形DP的更多相关文章
- Codeforces 1153D 树形DP
题意:有一个游戏,规则如下:每个点有一个标号,为max或min, max是指这个点的值是所有子节点中值最大的那一个,min同理.问如何给这颗树的叶子节点赋值,可以让这棵树的根节点值最大. 思路:很明显 ...
- Codeforces 1088E 树形dp+思维
比赛的时候看到题意没多想就放弃了.结果最后D也没做出来,还掉分了,所以还是题目做的太少,人太菜. 回到正题: 题意:一棵树,点带权值,然后求k个子连通块,使得k个连通块内所有的点权值相加作为分子除以k ...
- Codeforces 1179D 树形DP 斜率优化
题意:给你一颗树,你可以在树上添加一条边,问添加一条边之后的简单路径最多有多少条?简单路径是指路径中的点只没有重复. 思路:添加一条边之后,树变成了基环树.容易发现,以基环上的点为根的子树的点中的简单 ...
- CodeForces - 337D 树形dp
题意:一颗树上有且仅有一只恶魔,恶魔会污染距离它小于等于d的点,现在已经知道被污染的m个点,问恶魔在的可能结点的数量. 容易想到,要是一个点到(距离最远的两个点)的距离都小于等于d,那么这个点就有可能 ...
- CodeForces 219D 树形DP
D. Choosing Capital for Treeland time limit per test 3 seconds memory limit per test 256 megabytes i ...
- codeforces 337D 树形DP Book of Evil
原题直通车:codeforces 337D Book of Evil 题意:一棵n个结点的树上可能存在一个Evil,Evil危险范围为d,即当某个点与它的距离x<=d时,那么x是危险的. 现已知 ...
- Up and Down the Tree CodeForces - 1065F (树形dp)
链接 题目大意:给定$n$结点树, 假设当前在结点$v$, 有两种操作 $(1)$移动到$v$的子树内任意一个叶子上 $(2)$若$v$为叶子, 可以移动到距离$v$不超过$k$的祖先上 初始在结点$ ...
- codeforces 1053D 树形DP
题意:给一颗树,1为根节点,有两种节点,min或者max,min节点的值是它的子节点的值中最小的,max节点的值是它的子节点的值中最大的,若共有k个叶子,叶子的值依次为1~k. 问给每个叶子的值赋为几 ...
- Codeforces 1120D (树形DP 或 最小生成树)
题意看这篇博客:https://blog.csdn.net/dreaming__ldx/article/details/88418543 思路看这篇:https://blog.csdn.net/cor ...
随机推荐
- 正则化的L1范数和L2范数
范数介绍:https://www.zhihu.com/question/20473040?utm_campaign=rss&utm_medium=rss&utm_source=rss& ...
- 算法-python
选择排序:一个列表被分为无序列表和有序列表,选择排序就是拿无序列表的第一个和后面的每一个相比较,每一趟选择出最小的一个,添加进有序列表. def select_sort(list): for i in ...
- HashMap底层代码分析
public HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; //this.loadFactor为加载因子,其值为默认的加载因子常量:DEFAUL ...
- 一探究竟:善用 MaxCompute Studio 分析 SQL 作业
头疼的问题 MaxCompute 用户一个常见的问题是:同一个周期任务,为什么最近几天比之前慢了很多?或者为什么之前都能按时产出的作业最近经常破线? 通常来说,引起作业执行变慢的原因有:quota 组 ...
- 无题II
无题II Time Limit: 2000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- python中用os.walk查找全部的子文件
import os import shutil # 要遍历查找的文件所在的父文件夹 trajectory_filename =r"D:\mapping" # 要粘贴到的目标文件夹 ...
- jmeter(二十):Logic Controller:逻辑控制器(上)
逻辑控制器用来控制采样器(samplers)的执行顺序,根据实际需要定制执行规则.在控制器层级下面的所有的采样器都会当做一个整体,执行时也会一起被执行. Logic Controller种类: 以上L ...
- JS各种变量是true或者false列表
如果操作数是一个对象,返回true 如果操作数是一个空字符串,返回false如果操作数是一个非空字符串,返回true如果操作数是数值0,返回false如果操作数是任意非0数值(包括Infinity), ...
- docker 搭建gitlab
https://docs.gitlab.com/omnibus/docker/ https://blog.csdn.net/m0_37444820/article/details/81147452 h ...
- 从有状态应用(Session)到无状态应用(JWT),以及 SSO 和 OAuth2
不管用哪种方式认证用户,都可能被中间人攻击窃取 SessionID 或 Token,从而发生 CSRF 攻击.解决方式就是全站 HTTPS.现在 Let's Encrypt 已经支持免费的通配符 HT ...