[JSOI2018]潜入行动
我好菜啊,嘤嘤嘤
原来本地访问数组负下标不会报\(RE\)或者\(WA\),甚至能跑出正解啊
这道题还是非常呆的
我们发现\(k\)很小,于是断定这是一个树上背包
发现在一个点上安装控制器并不能控制这个点,可能需要到父亲那边才能控制这个点,于是我们设\(dp[i][j][0/1][0/1]\)表示在以\(i\)为根的子树里放置了\(j\)个监视器,控制了除了点\(i\)以外的点,在\(i\)点装没装控制器,\(i\)点有没有被控制
大力分类套论几个转移
\(dp[i][j][0][0]\)因为没有放监视器,必须要求其儿子们在他们的子树内部就被监视了,同时因为\(i\)还没有被监视,于是儿子不能放监视器,于是从\([0][1]\)转移
\(dp[i][j][1][0]\)因为放了监视器,能监视儿子,于是儿子们有没有被监视都可以,但是都不能放监视器,于是从\([0][1]\)和\([0][0]\)转移
\(dp[i][j][0][1]\)因为没有放监视器,儿子们必须全部被监视到从\([0][1]\)转移,因为\(i\)被监视,所以至少得有一个儿子放监视器,所以至少一个从\([1][1]\)转移
\(dp[i][j][1][1]\)放了监视器,而要求被监视,从四种状态都能转移,但是要求至少有一个转移是\([1][0]\)或\([1][1]\)(放了监视器)
直接树形背包转移,之后大力容斥掉没有选择那个至少要选择的情况就好了
发现\(dp[i][j][0][1]\)要减掉的正好是\(dp[i][j][0][0]\),\(dp[i][j][1][1]\)要减掉的正好是\(dp[i][j][1][0]\)
代码
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define LL long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int maxn=1e5+5;
const int mod=1e9+7;
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
struct E{int v,nxt;}e[maxn<<1];
int head[maxn],sum[maxn];
int dp[maxn][105][2][2];
int f[105][2][2];
int n,m,num;
inline void add(int x,int y) {e[++num].v=y;e[num].nxt=head[x];head[x]=num;}
inline int qm(int a) {return a>mod?a-mod:a;}
void dfs(int x,int fa) {
int cur=0;
sum[x]=1;
for(re int i=head[x];i;i=e[i].nxt) {
if(e[i].v==fa) continue;
int v=e[i].v;
dfs(v,x);cur++;
sum[x]+=sum[v];
int U=min(sum[x],m);
if(cur==1) {
for(re int k=0;k<=min(sum[v],m);k++) {
dp[x][k][0][0]=dp[v][k][0][1];
dp[x][k+1][1][0]=qm(dp[v][k][0][1]+dp[v][k][0][0]);
dp[x][k+1][1][1]=(dp[v][k][1][1]+dp[v][k][1][0])%mod+(dp[v][k][0][0]+dp[v][k][0][1])%mod;
dp[x][k+1][1][1]%=mod;
dp[x][k][0][1]=qm(dp[v][k][1][1]+dp[v][k][0][1]);
}
continue;
}
for(re int j=U;j>=0;--j) {
f[j][0][0]=dp[x][j][0][0],dp[x][j][0][0]=0;
f[j][0][1]=dp[x][j][0][1],dp[x][j][0][1]=0;
f[j][1][0]=dp[x][j][1][0],dp[x][j][1][0]=0;
f[j][1][1]=dp[x][j][1][1],dp[x][j][1][1]=0;
}
for(re int j=U;j>=0;--j)
for(re int k=0;k<=min(sum[v],m);k++) {
int t=j-k;
if(t<0) continue;
dp[x][j][0][0]=(dp[x][j][0][0]+1ll*f[t][0][0]*dp[v][k][0][1]%mod)%mod;
dp[x][j][1][0]=(dp[x][j][1][0]+1ll*f[t][1][0]*qm(dp[v][k][0][1]+dp[v][k][0][0])%mod)%mod;
dp[x][j][0][1]=(dp[x][j][0][1]+1ll*f[t][0][1]*qm(dp[v][k][1][1]+dp[v][k][0][1])%mod)%mod;
dp[x][j][1][1]=(dp[x][j][1][1]+1ll*f[t][1][1]*qm(qm(dp[v][k][1][1]+dp[v][k][1][0])+qm(dp[v][k][0][0]+dp[v][k][0][1]))%mod)%mod;
}
}
if(!cur) {dp[x][0][0][0]=dp[x][1][1][0]=1;return;}
for(re int j=0;j<=min(sum[x],m);j++)
dp[x][j][0][1]=(dp[x][j][0][1]-dp[x][j][0][0]+mod)%mod,
dp[x][j][1][1]=(dp[x][j][1][1]-dp[x][j][1][0]+mod)%mod;
}
int main() {
n=read();m=read();
for(re int x,y,i=1;i<n;i++)
x=read(),y=read(),add(x,y),add(y,x);
dfs(1,0);
printf("%d\n",(dp[1][m][0][1]+dp[1][m][1][1])%mod);
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是否放设备的方案数. 初 ...
- BZOJ5314 [Jsoi2018]潜入行动 【背包类树形dp】
题目链接 BZOJ5314 题解 设\(f[i][j][0|1][0|1]\)表示\(i\)为根的子树,用了\(j\)个监测器,\(i\)节点是否被控制,\(i\)节点是否放置的方案数 然后转移即可 ...
- BZOJ5314: [Jsoi2018]潜入行动 (树形DP)
题意:一棵树选择恰好k个结点放置监听器 每个监听器只能监听相邻的节点 问能使得所有节点被监听的种类数 题解:反正就是很well-known的树形DP了 至于时间复杂度为什么是nk 不会不学 很好想到四 ...
随机推荐
- DedeCMS修改管理员用户名
织梦内容管理系统(DedeCMS) 以简单.实用.开源而闻名,是国内最知名的PHP开源网站管理系统,也是使用用户最多的PHP类CMS系统,在经历多年的发展,目前的版本无论在功能,还是在易用性方面,都有 ...
- 使用C#利用cmd来调用java jar包获取其中的数据
其实也很简单,就是在C#中构建一个Process,启动jar包,并且给jar包传递参数 因为我并没有怎么学过JAVA,所以只写了个很小的Demo,就是根据传入的参数获取对应的数据 以下是JAVA De ...
- 大话JVM(一):垃圾收集算法
系列介绍|本系列主要是记录学习jvm过程中觉得重要的内容,方便以后复习 在说垃圾收集算法之前,先要说一下垃圾收集,从大的讲,垃圾收集需要考虑三件事情: 1.哪些内存需要回收 2.什么时候回收 3.如 ...
- vue + element ui 阻止表单输入框回车刷新页面
问题 在 vue+element ui 中只有一个输入框(el-input)的情况下,回车会提交表单. 解决方案 在 el-form 上加上 @submit.native.prevent 这个则会阻止 ...
- 基于Vue实现图片在指定区域内移动
当图片比要显示的区域大时,需要将多余的部分隐藏掉,我们可以通过绝对定位来实现,并通过动态修改图片的left值和top值从而实现图片的移动.具体实现效果如下图,如果我们移动的是div 实现思路相仿. 此 ...
- android studio *.apk does not exist on disk
Build -> Clean Project Restart Android Studio
- android studio 加载libs
eclipse 项目转 android studio libs 不能加载 导致不能导入 记录下:libs 放在和src 同路径 dependencies:增加 compile files('libs ...
- MySQL的索引与优化
写在前面:索引对查询的速度有着至关重要的影响,理解索引也是进行数据库性能调优的起点.考虑如下情况,假设数据库中一个表有10^6条记录,DBMS的页面大小为4K,并存储100条记录.如果没有索引,查询将 ...
- Android屏幕适配工具
这里需要用到一个jar包,下载拿到这个jar包后直接双击就可以生成市场大部分主流屏幕尺寸了.然后只要把生成好的xml尺寸文件拷贝到相应的value文件中即可.很方便,以后再也不用担心适配繁琐的问题了. ...
- Eclipse创建第一个Servlet(Dynamic Web Project方式)、第一个Web Fragment Project(web容器向jar中寻找class文件)
创建第一个Servlet(Dynamic Web Project方式) 注意:无论是以注解的方式还是xml的方式配置一个servlet,servlet的url-pattern一定要以一个"/ ...