【洛谷4815】[CCO2014] 狼人游戏(树形DP)
大致题意: 已知有平民和狼人共\(n\)个,每个平民会指控和保护任何人,每个狼人只会指控平民、保护狼人。告诉你\(m\)对指控与保护的关系,求有\(k\)个狼人的方案总数。
树形\(DP\)
这题目乍看很神仙,但一看给出的其他一些限制,就可以发现这就是一棵树!
而对于这种问题,容易想到用树形\(DP\)去求解。
我们可以设\(f_{i,0/1,j,0/1}\)来表示编号为\(i\)的节点作为平民/狼人时共有\(j\)个狼人的方案数,其中第二维分别表示上一次和这一次的答案,用了滚存。
则显然可以推得\(DP\)方程如下:
\]
\]
对于第一个方程,我们知道平民会指控和保护任何人,因此无论子节点为平民还是狼人都可以转移。
对于第二个方程,我们知道狼人只会指控平民、保护狼人,因此当指控关系时子节点必须为平民,当保护关系时子节点必须为狼人。
统计答案
由于这是一片森林,因此我们最后还需要统计答案,而这也是一个类似的过程。
我们可以设\(s_{0/1,j}\)来表示共有\(j\)个狼人的方案数,其中第一维类似于前面的第二位,分别表示上一次和这一次的答案。
若我们从\(0\)号节点向所有根节点连边,则转移式其实是几乎一样的:
\]
其实很好理解,这与上面的式子就少了枚举当前节点是平民还是狼人,而\(0\)号节点作为虚拟节点,显然都不是嘛。。。
具体实现详见代码。
代码
#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<tepename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define RC Reg char
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 200
#define X 1000000007
#define min(x,y) ((x)>(y)?(x):(y))
#define add(x,y,v) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y,e[ee].op=v)
#define Inc(x,y) ((x+=(y))>=X&&(x-=X))
using namespace std;
int n,m,k,ee,deg[N+5],lnk[N+5];struct edge {int to,nxt;char op;}e[N+5];
I int XSum(RI x,CI y) {return x+y>=X?x+y-X:x+y;}
class TreeDper//树形DP
{
private:
int s[2][N+5],t[N+5],g[N+5],f[N+5][2][N+5][2];
I void DP(CI x)//DP
{
g[x]=f[x][0][0][0]=f[x][0][1][1]=1;for(RI i=lnk[x],j,l,op=1;i;i=e[i].nxt,op^=1)//初始化信息,枚举子节点
{
for(memset(f[x][op],0,sizeof(f[x][op])),DP(e[i].to),j=min(k,g[x]);~j;--j) for(l=min(k-j,g[e[i].to]);~l;--l)//枚举状态进行转移
{
Inc(f[x][op][j+l][0],1LL*f[x][op^1][j][0]*XSum(f[e[i].to][t[e[i].to]][l][0],f[e[i].to][t[e[i].to]][l][1])%X),
Inc(f[x][op][j+l][1],1LL*f[x][op^1][j][1]*f[e[i].to][t[e[i].to]][l][e[i].op=='D']%X);
}g[x]+=g[e[i].to],t[x]^=1;//更新size
}
}
public:
I int GetAns()//与上面的过程类似
{
RI i,j,l,op=1;for(s[0][0]=1,i=lnk[0];i;i=e[i].nxt,op^=1)
for(memset(s[op],0,sizeof(s[op])),DP(e[i].to),j=k;~j;--j) for(l=min(k-j,g[e[i].to]);~l;--l)
Inc(s[op][j+l],1LL*s[op^1][j]*XSum(f[e[i].to][t[e[i].to]][l][0],f[e[i].to][t[e[i].to]][l][1])%X);
return s[op^1][k];
}
}T;
int main()
{
ios::sync_with_stdio(false);
RI i,x,y,ans=1;RC op;for(cin>>n>>k>>m,i=1;i<=m;++i) cin>>op>>x>>y,add(x,y,op),++deg[y];//读入+建边
for(i=1;i<=n;++i) !deg[i]&&add(0,i,'*');return printf("%d",T.GetAns()),0;//求解并输出
}
【洛谷4815】[CCO2014] 狼人游戏(树形DP)的更多相关文章
- 洛谷 P3177 [HAOI2015]树上染色 树形DP
洛谷 P3177 [HAOI2015]树上染色 树形DP 题目描述 有一棵点数为 \(n\) 的树,树边有边权.给你一个在 \(0 \sim n\)之内的正整数 \(k\) ,你要在这棵树中选择 \( ...
- 洛谷 P4201 设计路线 [NOI2008] 树形dp
正解:树形dp 解题报告: 大概是第一道NOI的题目?有点激动嘻嘻 然后先放个传送门 先大概港下这题的题意是啥qwq 大概就是给一棵树,然后可以选若干条链把链上的所有边的边权变成0,但是这些链不能有交 ...
- 洛谷P1040 加分二叉树(树形dp)
加分二叉树 时间限制: 1 Sec 内存限制: 125 MB提交: 11 解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...
- 洛谷P4438 道路 [HNOI/AHOI2018] 树形dp
正解:树形dp 解题报告: 传送门! 昂首先看懂题目趴QwQ大概就是说有棵满二叉树,有n个叶子节点(乡村)和n-1个非叶子节点,然后这棵树的每个节点有三个属性abc,对每个非叶子节点可以从与子节点的两 ...
- 洛谷 P3267 [JLOI2016/SHOI2016]侦察守卫(树形dp)
题面 luogu 题解 树形\(dp\) \(f[x][y]表示x的y层以下的所有点都已经覆盖完,还需要覆盖上面的y层的最小代价.\) \(g[x][y]表示x子树中所有点都已经覆盖完,并且x还能向上 ...
- 洛谷P1351 联合权值(树形dp)
题意 题目链接 Sol 一道很简单的树形dp,然而被我写的这么长 分别记录下距离为\(1/2\)的点数,权值和,最大值.以及相邻儿子之间的贡献. 树形dp一波.. #include<bits/s ...
- 洛谷P4099 [HEOI2013]SAO(树形dp)
传送门 HEOI的题好珂怕啊(各种意义上) 然后考虑树形dp,以大于为例 设$f[i][j]$表示$i$这个节点在子树中排名第$j$位时的总方案数(因为实际只与相对大小有关,与实际数值无关) 我们考虑 ...
- 洛谷 P1351 联合权值 —— 树形DP
题目:https://www.luogu.org/problemnew/show/P1351 树形DP,别忘了子树之间的情况(拐一下距离为2). 代码如下: #include<iostream& ...
- 洛谷 P2634 聪聪可可 —— 树形DP / 点分治
题目:https://www.luogu.org/problemnew/show/P2634 今天刚学了点分治,做例题: 好不容易A了,结果发现自己写的是树形DP...(也不用找重心)(比点分治快) ...
- 洛谷P3047 [USACO12FEB]Nearby Cows(树形dp)
P3047 [USACO12FEB]附近的牛Nearby Cows 题目描述 Farmer John has noticed that his cows often move between near ...
随机推荐
- AnnotationConfigApplicationContext
package com.test; import java.io.IOException; import java.io.InputStream; import java.net.URL; impor ...
- 逐行创建、读取并写入txt(matlab) && 生成文件夹里文件名的.bat文件
fidin=fopen('C:\Users\byte\Desktop\新建文件夹 (4)\tr4.txt','r'); fidout=fopen('C:\Users\byte\Desktop\新建文件 ...
- 二分搜索 - Binary Search
二分搜索是一种在有序数组中寻找目标值的经典方法,也就是说使用前提是『有序数组』.非常简单的题中『有序』特征非常明显,但更多时候可能需要我们自己去构造『有序数组』.下面我们从最基本的二分搜索开始逐步深入 ...
- 使用hive数据仓库中遇到的问题
1. 原因:hive版本过高.我用的是3.1.1最高版本,所以报此错.
- ExtJS 开发总结
1. ExtJS的定位是RIA,和Prototype.jQuery等类库的定位不同.使用ExtJS做开发,就是意味着以客户端开发为主,不然就不叫RIA框架了,而Prototype.jQuery等只是辅 ...
- java 与 数据库的连接
Eclipse中使用SQL server 2017数据库 一.准备材料 要能够使用数据库就要有相应的JDBC,所以我们要去Microsoft官网下载https://www.microsoft.com/ ...
- javascript 例外处理Try{}catch(e){}
程序开发中,编程人员经常要面对的是如何编写代码来响应错误事件的发生,即例外处理(exception handlers).如果例外处理代码设计得周全,那么最终呈现给用户的就将是一个友好的界面.否则,就会 ...
- leetcode 182. Duplicate Emails having的用法 SQL执行顺序
https://leetcode.com/problems/duplicate-emails/description/ 首先sql的执行顺序是 from-->where-->group b ...
- 性能测试工具LoadRunner20-LR之Controller Service-Level Agreement(服务水平协议)
SLA是为负载测试场景定义的具体目标.例如,评测脚本中任意数量事务的平均响应时间,可以定义具体的目标或阈值.测试运行结束之后,LR将你定义的目标与实际录制的平均事务响应时间进行比较.如果实际的平均事务 ...
- linux下Python2.7编译安装PyQt5
---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:在ubuntu系 ...