NC20811 蓝魔法师
题目
题目描述
“你,你认错人了。我真的,真的不是食人魔。”--蓝魔法师
给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于k,两种方案不同当且仅当存在一条边在一个方案中被删除,而在另一个方案中未被删除,答案对998244353取模
输入描述
第一行两个整数n,k, 表示点数和限制
2 <= n <= 2000, 1 <= k <= 2000
接下来n-1行,每行包括两个整数u,v,表示u,v两点之间有一条无向边
保证初始图联通且合法
输出描述
共一行,一个整数表示方案数对998244353取模的结果
示例1
输入
5 2
1 2
1 3
2 4
2 5
输出
7
题解
知识点:树形dp,背包dp,计数dp。
显然是个树上背包,但涉及组合计数。
设 \(dp[u][i]\) 表示以 \(u\) 为根的子树划分成大小不大于 \(k\) 连通块,且 \(u\) 所在连通块大小为 \(i\) 的方案数。这道题要剪枝,转移方程我用了刷表法。下面代码有打表和刷表的对比,明显刷表法更容易写出最佳的循环边界。转移方程为:
\begin{array}{l}
dp[u][i+j] &= dp[u][i + j] + dp[u][i] \cdot dp[v][j]\\
dp[u][i] &= dp[u][i] + \sum dp[v][j]
\end{array}
\right .
\]
- 连接 \((u,v)\) , \(dp[u][i]\) 与 \(dp[v][j]\) 用乘法原理合并,最后得到 \(dp[u][i+j]\) ,显然 \(i+j\) 要小于等于 \(k\) 。 $i \in [1,\min(sz[u],k)] $ , \(j \in [1,\min (sz[v],k)]\) ,两者都要倒序遍历保证 \(i+j\) 是倒序的。
- 断开 \((u,v)\) , \(dp[u][i]\) 的方案加上 \(dp[v][j]\) 的所有方案数。为了防止 \(dp[u][i]\) 的更新影响 \(i+j\) ,因此这个更新要在一次 \(i\) 的更新最后执行。
时间复杂度 \(O(nk^2)\)
空间复杂度 \(O(nk)\)
代码
#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
int n, k;
vector<int> g[2007];
int dp[2007][2007], sz[2007];
/* void dfs(int u, int fa) {
dp[u][1] = 1;
sz[u] = 1;
for (auto v : g[u]) {
if (v == fa) continue;
dfs(v, u);
sz[u] += sz[v];
int sumv = 0;
for (int i = 1;i <= sz[v];i++) sumv = (sumv + dp[v][i]) % mod;
for (int i = min(sz[u], k);i >= 1;i--) {
dp[u][i] = 1LL * dp[u][i] * sumv % mod;///断开
for (int j = max(1, sz[v] + i - sz[u]);j <= min({ i, k,sz[v] });j++) ///链接
dp[u][i] = (dp[u][i] + 1LL * dp[u][i - j] * dp[v][j]) % mod;
}
}
} */
///复杂度和常数比上面一种方式少一点,甚至比上面边界好写很多
void dfs(int u, int fa) {
dp[u][1] = 1;
sz[u] = 1;
for (auto v : g[u]) {
if (v == fa) continue;
dfs(v, u);
int sumv = 0;
for (int i = 1;i <= sz[v];i++) sumv = (sumv + dp[v][i]) % mod;
for (int i = min(sz[u], k);i >= 1;i--) {
for (int j = min(sz[v], k);j >= 1;j--) {
if (i + j > k) continue;///也可以用tmp暂存的方法,然后顺序更新,就可以直接break,否则只能倒叙
dp[u][i + j] = (dp[u][i + j] + 1LL * dp[u][i] * dp[v][j]) % mod;
}
dp[u][i] = 1LL * dp[u][i] * sumv % mod;
}
sz[u] += sz[v];
}
}///复杂度 O(nk^2),剪枝以后复杂度不变但常数会少巨多,因为少遍历了很多不可能的状态
int main() {
std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> k;
for (int i = 1;i < n;i++) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0);
int ans = 0;
for (int i = 1;i <= k;i++) ans = (ans + dp[1][i]) % mod;
cout << ans << '\n';
return 0;
}
NC20811 蓝魔法师的更多相关文章
- 牛客网 Wannafly挑战赛27 蓝魔法师
蓝魔法师 链接: https://www.nowcoder.com/acm/contest/215/C 来源:牛客网 题目描述 "你,你认错人了.我真的,真的不是食人魔."--蓝魔 ...
- Wannafly挑战赛27 C蓝魔法师
链接Wannafly挑战赛27 C蓝魔法师 给出一棵树,求有多少种删边方案,使得删后的图每个连通块大小小于等于\(k\),\(n,k\leq 2*10^3\) 假设我们正在考虑\(i\)这个子树,那么 ...
- Wannafly挑战赛27
Wannafly挑战赛27 我打的第一场$Wannafly$是第25场,$T2$竟然出了一个几何题?而且还把我好不容易升上绿的$Rating$又降回了蓝名...之后再不敢打$Wannafly$了. 由 ...
- BZOJ-5055-膜法师(离散化+树状数组)
Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...
- [BZOJ 5055]膜法师
Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...
- bzoj5055 膜法师
Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...
- BZOJ_5055_膜法师_树状数组+离散化
BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...
- bzoj 5055: 膜法师——树状数组
Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...
- bzoj 5055: 膜法师 -- 树状数组
5055: 膜法师 Time Limit: 10 Sec Memory Limit: 128 MB Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇 ...
- JZOJ.5280【NOIP2017模拟8.15】膜法师
Description
随机推荐
- Nginx arm编译安装
Nginx arm编译安装 背景 计划编译一套产品. 能够比较方便快捷的进行 nginx的交付. 主要思想是源码编译 不仅能够在arm上面运行 也可以在x86上面编译 考虑性能还有一些扩展性. 高效处 ...
- [转帖]一个Linux 内核 bug 导致的 TCP连接卡死
https://plantegg.github.io/2022/10/10/Linux%20BUG%E5%86%85%E6%A0%B8%E5%AF%BC%E8%87%B4%E7%9A%84%20TCP ...
- [转帖]SQL标准
SQL 的标准 1986 年 10 月,美国国家标准协会 ANSI 采用 SQL 作为关系数据库管理系统的标准语言,并命名为 ANSI X3. 135-1986,后来国际标准化组织(ISO)也采纳 S ...
- [转帖]Linux 内核 | 网络流量限速方案大 PK
https://maimai.cn/article/detail?fid=1674483493&efid=UXVPILU_JTlqLrYhTkDStA 网络流量限速是一个经久不衰的话题,Lin ...
- [转帖]ipset详解
https://zhuanlan.zhihu.com/p/489103374 ipset创建:create 创建一个新的ipset集合:ipset create SETNAME TYPENAME SE ...
- gcore的学习
gcore的学习-解决jmap无法生成dump文件的一种方法 背景 周末在跆拳道馆看孩子练跆拳道. 开着笔记本翻到了 扣钉日记 公众号里面的讲解 想着自己也遇到过无法保存dump文件的情况. 所以想学 ...
- [转帖]适用于 Azure VM 的 TCP/IP 性能优化
https://learn.microsoft.com/zh-cn/azure/virtual-network/virtual-network-tcpip-performance-tuning?con ...
- 一次w3wp出现crash的简单解决方案
1. 前几天同事求助, 说一台服务器iis出现多次崩溃的现象,重启iis就可以了. 具体原因不明. 之前遇到过类似的问题 感觉最彻底的解决方案是 抓dump然后使用windbg 进行分析. 但是自 ...
- Rsync的简单使用
Rsync的简单使用 需求 一个运行很久的系统里面可能包含了非常多的垃圾文件. 但是又不可能随便删除, 很多垃圾可能有某些奇葩的用法. 有时候新建一个应用复制文件的话比较浪费磁盘和带宽. 所以这里简单 ...
- CentOS8 设置开机自动登录账户的方法
CentOS8 设置开机自动登录账户的方法 修改/etc/gdm/custom.conf文件, 并且添加内容即可. vim /etc/gdm/custom.conf # 在配置节下添加如下内容. [d ...