题意:

  有n个点,编号为1~n。有的点颜色是黑色,有的点颜色是白色,有的点的颜色待涂。你还可以连一些边,但这些边一定是从小编号连到大编号的点。

  对于一个确定的图,我们去统计有多少条路径满足“该路径经过的所有点的颜色都是黑白相间的”,如果这种路径总数的奇偶性为p(p是输入的,p=0或1),那么该图就被称为好图

  我们需要统计所有图中,好图的个数。答案对1e9+7取模。

分析:

  我们先考虑对于一个给定的图,如何求出这种路径的总数

  dp[i][0]表示点i是黑点,以点i为终点的所有路径的条数;dp[i][1]表示点i是白点,以点i为终点的所有路径的条数

  那么只需要从前往后dp一下就能求出结果了

  注意我们只关系奇偶性,所以是在模2意义下,那么dp值只有0和1两种取值

  那么有一种显然的dp套dp的思路:f[i][S]表示已经做完了前i个点,前i个点的dp值是S情况下的图的个数

  但是最多有50个点,状态是2^50,这样不能解决

  仔细分析后发现,我们关心的并不是前i-1个点的具体dp值,我们关心的只是dp[j][0]=0、dp[j][0]=1、dp[j][1]=0、dp[j][1]=1的状态的分别的数目!

  于是dp[i][ew][ow][eb][ob]表示前i个点,有ew个even-white点(即以某白点为终点的路径总数是偶数,后面同理),有ow个odd-white点,有eb个even-black点,有ob个odd-black点的情况下,图的个数

  那么最后答案就是满足(ow+ob)%2==p的状态的图的个数的总和

  这样复杂度是O(n^5),我们考虑优化一下

  首先很明显,ob=i-ew-ow-eb,于是可以省掉一个维的状态,复杂度就变成O(n^4)了,可以通过

  再进一步,我们发现偶点是随便连的,于是我们只需要记状态为dp[i][ow][ob]就行了,时间复杂度O(n^3)

 #include<bits/stdc++.h>
using namespace std;
const int maxn=,mod=1e9+;
int dp[maxn+][maxn+][maxn+][maxn+];
int c[maxn+];
int n,p;
int pw[maxn+];
void inc(int&a,int b)
{
a=(a+b)%mod;
}
int main()
{
scanf("%d%d",&n,&p);
for(int i=;i<=n;++i) scanf("%d",&c[i]);
pw[]=;
for(int i=;i<=maxn;++i) pw[i]=pw[i-]*2LL%mod;
if(c[]==||c[]==-) dp[][][][]=;
if(c[]==||c[]==-) dp[][][][]=;
for(int i=;i<=n;++i)
for(int ew=;ew<=i;++ew)
for(int ow=;ow<=i;++ow)
for(int eb=;eb<=i;++eb)
{
if(ow+ew+eb>i) continue;
int ob=i-ew-ow-eb;
if(c[i]==||c[i]==-)
{
if(ow+ew!=)
{
long long s=;
if(ow>=)
if(ob==) s=dp[i-][ew][ow-][eb];
else s=1LL*pw[ob-]*dp[i-][ew][ow-][eb]%mod;
if(ew>=)
if(ob>=) s+=1LL*pw[ob-]*dp[i-][ew-][ow][eb]%mod;
s%=mod;
s=s*pw[eb+ew+ow-]%mod;
inc(dp[i][ew][ow][eb],(int)s);
}
}
if(c[i]==||c[i]==-)
{
if(ob+eb!=){
long long s=;
if(ob>=)
if(ow==) s=dp[i-][ew][ow][eb];
else s=1LL*pw[ow-]*dp[i-][ew][ow][eb]%mod;
if(eb>=)
if(ow>=) s+=1LL*pw[ow-]*dp[i-][ew][ow][eb-]%mod;
s%=mod;
s=s*pw[eb+ob+ew-]%mod;
inc(dp[i][ew][ow][eb],(int)s);
}
}
}
int ans=;
for(int ew=;ew<=n;++ew)
for(int ow=;ow<=n;++ow)
for(int eb=;eb<=n;++eb)
if(ew+ow+eb<=n)
if((ow+n-ew-ow-eb)%==p)
inc(ans,dp[n][ew][ow][eb]);
printf("%d\n",ans);
return ;
}

codeforces 979E(dp套dp)的更多相关文章

  1. Codeforces 372B Counting Rectangles is Fun:dp套dp

    题目链接:http://codeforces.com/problemset/problem/372/B 题意: 给你一个n*m的01矩阵(1 <= n,m <= 40). 然后有t组询问( ...

  2. bzoj 3864: Hero meet devil [dp套dp]

    3864: Hero meet devil 题意: 给你一个只由AGCT组成的字符串S (|S| ≤ 15),对于每个0 ≤ .. ≤ |S|,问 有多少个只由AGCT组成的长度为m(1 ≤ m ≤ ...

  3. [模板] dp套dp && bzoj5336: [TJOI2018]party

    Description Problem 5336. -- [TJOI2018]party Solution 神奇的dp套dp... 考虑lcs的转移方程: \[ lcs[i][j]=\begin{ca ...

  4. luogu 4158 粉刷匠 dp套dp

    dp套dp 每个木板是个递推的dp,外部是个分组背包 #include<bits/stdc++.h> #define rep(i,x,y) for(register int i=x;i&l ...

  5. DP套DP

    DP套DP,就是将内层DP的结果作为外层DP的状态进行DP的方法. [BZOJ3864]Hero meet devil 对做LCS的DP数组差分后状压,预处理出转移数组,然后直接转移即可. tr[S] ...

  6. 【BZOJ3864】Hero meet devil DP套DP

    [BZOJ3864]Hero meet devil Description There is an old country and the king fell in love with a devil ...

  7. dp 套 dp扯谈

    1.[扯谈概念] \(dp\) 套 \(dp\) 其实也就是 \(dp\) . 这里就定义下面两个概念: 内层 \(dp\) 表示的是被套在里面的那个 \(dp\) 外层 \(dp\) 表示的是最外面 ...

  8. P4590-[TJOI2018]游园会【dp套dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P4590 题目大意 给出一个长度为\(m\)的字符串\(s\). 对于每个\(k\in[0,m]\)求有多少个长度为 ...

  9. 洛谷 P5279 - [ZJOI2019]麻将(dp 套 dp)

    洛谷题面传送门 一道 dp 套 dp 的 immortal tea 首先考虑如何判断一套牌是否已经胡牌了,考虑 \(dp\)​​​​​.我们考虑将所有牌按权值大小从大到小排成一列,那我们设 \(dp_ ...

随机推荐

  1. LeetCode(226)Invert Binary Tree

    题目 分析 交换二叉树的左右子树. 递归非递归两种方法实现. AC代码 class Solution { public: //递归实现 TreeNode* invertTree(TreeNode* r ...

  2. Aizu - 1386 Starting a Scenic Railroad Service (思维乱搞)

    给你n个区间,求: 1:最多有多少区间与同一个区间相交. 2:相交部分的最大区间数目. Sample Input 1 4 1 3 1 3 3 6 3 6 Sample Output 1 2 2 Sam ...

  3. HDU 3072 SCC Intelligence System

    给出一个带权有向图,要使整个图连通.SCC中的点之间花费为0,所以就先缩点,然后缩点后两点之间的权值为最小边的权值,把这些权值累加起来就是答案. #include <iostream> # ...

  4. luogu2765 魔术球问题

    发现好像没人来证明贪心啊--那我来写一下它的证明 欲证明:放一个数在已有的柱上(如果可以)总是比新开一个柱更优的 假如已经放了x1..x2....xu..xv..xw.... 现在我要放xx 我有两种 ...

  5. java中,为什么char类型数组可以直接用数组名打印,打印结果居然不是地址值!

    char类型的数组就相当于一个字符串. 因为输出流System.out是PrintStream对象,PrintStream有多个重载的println方法,其中一个就是public void print ...

  6. csrf 攻击及防御

    1.什么是CSRF攻击: CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:C ...

  7. R语言采坑系列——Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA

    用ggplot2的geom_density_2d时,总是不能填充图案,并报错: Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA 解 ...

  8. 解决webstorm安装babel卡死问题

    2017.07.16 现在大家可以直接使用yarn的方式安装包,可以解决babel目录过长导致webstorm卡死的问题. yarn的安装不会执行组件命令就不会导致node_modules下面继续嵌套 ...

  9. hibernate框架的搭建与简单实现增删改

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自 ...

  10. oracle查询包含大小写的数据

    查询包含小写的所有数据: select oper_no from info_oper where regexp_like(oper_no,'[[:lower:]]'); select oper_no  ...