【JSOI2018】潜入行动
【JSOI2018】潜入行动




树形\(DP\)。设\(f_{i,j,0/1,0/1}\)表示以\(i\)为根的子树中,用了\(j\)个监听器,是否放置了监听器,是否被监听的方案数。转移就多讨论几种情况就好了。
关键问题是直接这么做是\(O(NK^2)\)的。
解决方案就是,我们别\(DP\)边维护子树的大小\(size\),每次枚举子树的监听器的时候不能超过\(min\{size,k\}\)。这看似只是一个常数优化,但其实可以吧复杂度降到\(O(NK)\)。
可以看这位dalao的证明
\(DP\)的时候按合并的两个子树大小分为三种情况:
- 两个子树\(size\)均大于\(k\)。
- 其中一个大于\(k\),另一个小于等于\(k\)
- 两个子树大小均小于等于\(k\)
然后对于复杂度的分析:
- 合并一次\(O(k^2)\),但是最多这样合并\(\frac{n}{k}\)次。
- 考虑小的那颗子树每个点贡献一次复杂度。并且以后不会再贡献,因为合并后子树大小大于\(k\)了。
- 考虑每个点贡献的次数就是每个合并时另一颗子树的大小。所以每个点最多贡献\(K\)次。
所以复杂度\(O(NK)\)
代码:
#include<bits/stdc++.h>
#define ll long long
#define N 100005
using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}
const ll mod=1e9+7;
int n,k;
struct road {int to,next;}s[N<<1];
int h[N],cnt;
void add(int i,int j) {s[++cnt]=(road) {j,h[i]};h[i]=cnt;}
ll f[N][105][2][2];
ll g[105][2][2];
int size[N];
void dfs(int v,int fr) {
size[v]=1;
f[v][0][0][0]=1;
f[v][1][1][0]=1;
for(int i=h[v];i;i=s[i].next) {
int to=s[i].to;
if(to==fr) continue ;
dfs(to,v);
int lim=min(k,size[v]);
memset(g,0,sizeof(g));
for(int j=0;j<=lim;j++) {
int lim2=min(size[to],k-j);
for(int q=0;q<=lim2;q++) {
(g[j+q][0][0]+=f[v][j][0][0]*f[to][q][0][1])%=mod;
(g[j+q][0][1]+=f[v][j][0][1]*(f[to][q][0][1]+f[to][q][1][1])+f[v][j][0][0]*f[to][q][1][1])%=mod;
(g[j+q][1][0]+=f[v][j][1][0]*(f[to][q][0][1]+f[to][q][0][0]))%=mod;
(g[j+q][1][1]+=f[v][j][1][1]*(f[to][q][0][0]+f[to][q][0][1]+f[to][q][1][0]+f[to][q][1][1]))%=mod;
(g[j+q][1][1]+=f[v][j][1][0]*(f[to][q][1][0]+f[to][q][1][1]))%=mod;
}
}
memcpy(f[v],g,sizeof(g));
size[v]+=size[to];
}
}
int main() {
n=Get(),k=Get();
int a,b;
for(int i=1;i<n;i++) {
a=Get(),b=Get();
add(a,b),add(b,a);
}
dfs(1,0);
int ans=0;
ans=(ans+f[1][k][0][1]+f[1][k][1][1])%mod;
cout<<ans;
return 0;
}
【JSOI2018】潜入行动的更多相关文章
- 【BZOJ5314】[JSOI2018]潜入行动(动态规划)
[BZOJ5314][JSOI2018]潜入行动(动态规划) 题面 BZOJ 洛谷 题解 不难想到一个沙雕\(dp\),设\(f[i][j][0/1][0/1]\)表示当前点\(i\),子树中一共放了 ...
- BZOJ5314: [Jsoi2018]潜入行动
BZOJ5314: [Jsoi2018]潜入行动 https://lydsy.com/JudgeOnline/problem.php?id=5314 分析: 裸树形背包,设\(f[x][i][0/1] ...
- [bzoj5314][Jsoi2018]潜入行动_树形背包dp
潜入行动 bzoj-5314 Jsoi-2018 题目大意:题目链接. 注释:略. 想法: 学长给我们除了一套考试题,三个学长一人一道这是T1. 好吧好吧,傻逼背包...... 复杂度$O(nk)$. ...
- BZOJ5314:[JSOI2018]潜入行动——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=5314 https://www.luogu.org/problemnew/show/P4516 ht ...
- bzoj 5314: [Jsoi2018]潜入行动
Description 外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY已经联系好了黄金舰队,打算联合所有JSO Ier抵御外星人的进攻.在黄金舰队就位之前,JYY打算事先了解外星人 ...
- [loj2546][JSOI2018]潜入行动(树形DP)
题目描述 外星人又双叒叕要攻打地球了,外星母舰已经向地球航行!这一次,JYY 已经联系好了黄金舰队,打算联合所有 JSOIer 抵御外星人的进攻. 在黄金舰队就位之前,JYY 打算事先了解外星人的进攻 ...
- luogu P4516 [JSOI2018]潜入行动
LINK:潜入行动 初看题感觉很不可做 但是树形dp的状态过于明显. 容易设\(f_{x,j,l,r}\)表示x为根子树内放了j个设备且子树内都被覆盖l表示x是否被覆盖r表示x是否放设备的方案数. 初 ...
- [JSOI2018]潜入行动
题目 我好菜啊,嘤嘤嘤 原来本地访问数组负下标不会报\(RE\)或者\(WA\),甚至能跑出正解啊 这道题还是非常呆的 我们发现\(k\)很小,于是断定这是一个树上背包 发现在一个点上安装控制器并不能 ...
- BZOJ5314 [Jsoi2018]潜入行动 【背包类树形dp】
题目链接 BZOJ5314 题解 设\(f[i][j][0|1][0|1]\)表示\(i\)为根的子树,用了\(j\)个监测器,\(i\)节点是否被控制,\(i\)节点是否放置的方案数 然后转移即可 ...
- BZOJ5314: [Jsoi2018]潜入行动 (树形DP)
题意:一棵树选择恰好k个结点放置监听器 每个监听器只能监听相邻的节点 问能使得所有节点被监听的种类数 题解:反正就是很well-known的树形DP了 至于时间复杂度为什么是nk 不会不学 很好想到四 ...
随机推荐
- .NET 中的序列化 & 反序列化
序列化:将对象的状态信息及类型信息,转换为一种易于传输或存储形式(流,即字节序列)的过程. 下图为序列化过程图示,图片来自微软官方文档: 反序列化:与序列化相反,将流转换为对象的过程. 常用的有二进制 ...
- 浅析多线程的对象锁和Class锁
一.前言 本来想在另外一篇文章说的,发现可能篇幅有点大,所以还是另开一篇博文来说好了.知识参考<Java多线程编程核心技术>,评价下这本书吧——大量的代码,简单的说明,真像在看博客.不过这 ...
- Fundebug能够捕获这些BUG
摘要:Fundebug的JavaScript监控插件更新至0.1.0,可以监控3种不同类型的前端BUG:JavaScript执行错误.资源加载错误.HTTP请求错误. 从简单的onerror开始,Fu ...
- CSS-水平和垂直居中
div中水平和垂直居中 width:200px;height:200px; /*设置div的大小*/ border:1px solid green; /*边框*/ text-align: center ...
- js-clickNumCount.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- HTML空格符号 nbsp; ensp; emsp; 介绍以及实现中文对齐的方法
一:不同空格符合的区别 半角的不断行的空白格(推荐使用) 半角的空格 全角的空格 详细的含义: :这是我们使用最多的空格,也就是按下space键产生的空格.在HTML中,如果你用空格 ...
- 【20190226】JavaScript-知识点记录:dom0级事件,dom2级事件
DOM0级事件处理程序: 通过将元素的事件处理程序属性(如onclick)的值设置为一个函数来指定事件处理程序的方法称为DOM0级方法,它被认为是元素的方法,这时候的事件处理程序是在元素的作用域中运行 ...
- [C语言]易错知识点、小知识点复习(1)
1. 计算机只能识别由0和1组成的二进制指令,需要将用高级语言(如C.C++)编写的源程序(.c..cpp)编译成二进制目标文件(.obj).一个程序可以根据需要写在不同的文件里,编译是以文件为单位进 ...
- 图说OOP基础(一)
本文用图形化的形式描述OOP的相关知识.对OOP进行系统化的梳理,以便掌握,仅供学习分享使用,如有不足之处,还请指正. 涉及知识点: OOP的相关知识 OOP知识总图 [Object-Orientat ...
- FreeSWITCH1.6安装教程Centos
介绍 FreeSWITCH是个网络电话转化器,相当与网络转换器,不过这个是用于IP电话,构建公司的电话通讯系统需要用该技术,因为按照官方文档无法成功安装. 本文目的:FreeSWITCH安装步骤 官方 ...