[传送门[(http://www.51nod.com/Challenge/Problem.html#!#problemId=1518)

解题思路

  直接算不好算,考虑容斥,但并不能把行和列一起加进去容斥,这会使时间复杂度非常高,那么就考虑枚举行后\(dp\)。设\(f[i]\)表示存在\(i\)列有线,任意一行无线的方案数,\(g[i[\)表示至少有\(i\)列有线,任意一行无线的方案数,那么

\[g[i]=\sum\limits_{k=i}^n C(i,k)f[i]
\]

二项式反演得

\[f[0]=\sum\limits_{k=0}^n(-1)^kg[k]C(k,0)
\]

那么只需要考虑求出\(g\)。

  首先要预处理出来\(dp[i][j]\)表示\(i\)行\(j\)列任意放的方案数,那么算答案时可以先枚举哪几列有线,然后算出\(g[i]\),\(g[i]\)就是首先把\(dp\)数组合并,直观理解就是把那几块拼在一起,然后减去\(j<i\)的\(g[j]\),就是保证行没有线,之后就可以算答案了。时间复杂度O(\(2^n n^2)\)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#define int long long using namespace std;
const int N=18;
const int MOD=1e9+7;
typedef long long LL; int f[N][N],n,m,g[N],ans,dp[2][(1<<(17))],tmp[N];
vector<int> v; inline void DP(int lim){
memset(dp,0,sizeof(dp));
int now=0; dp[0][(1<<lim)-1]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=lim;j++){
now^=1; memset(dp[now],0,sizeof(dp[now]));
for(int S=0;S<(1<<lim);S++)if(dp[now^1][S]){
if(S&1) (dp[now][S>>1]+=dp[now^1][S])%=MOD;
if(i!=1 && (!(S&1)))
(dp[now][(S>>1)|(1<<(lim-1))]+=dp[now^1][S])%=MOD;
if(j!=1 && (S&1) && lim>1 && (!(S&(1<<(lim-1)))))
(dp[now][(S>>1)|(1<<(lim-1))|(1<<(lim-2))]+=dp[now^1][S])%=MOD;
}
}
f[i][lim]=dp[now][(1<<lim)-1];
}
} inline void prework(){
for(int i=1;i<=m;i++) DP(i);
} signed main(){
n=m=16; prework();
while(~scanf("%lld%lld",&n,&m)){
for(int S=(1<<(m-1));S<(1<<m);S++){
int lst=0; v.clear();
for(int i=1;i<=m;i++)
if(S&(1<<(i-1))) v.push_back(i-lst),lst=i;
for(int i=1;i<=n;i++){
tmp[i]=1;
for(int j=0;j<v.size();j++)
tmp[i]=1ll*tmp[i]*f[i][v[j]]%MOD;
}
for(int i=1;i<=n;i++){
g[i]=tmp[i];
for(int k=1;k<i;k++)
g[i]-=1ll*g[k]*tmp[i-k]%MOD,g[i]%=MOD;
}
if(v.size()&1) (ans+=g[n])%=MOD;
else (ans-=g[n])%=MOD;
} ans=(ans%MOD+MOD)%MOD;
printf("%lld\n",ans); ans=0;
}
return 0;
}

51nod 1518 稳定多米诺覆盖(容斥+二项式反演+状压dp)的更多相关文章

  1. 【做题】51NOD1518 稳定多米诺覆盖——容斥&dp

    题意:求有多少种方案,用多米诺骨牌覆盖一个\(n\times m\)的棋盘,满足任意一对相邻行和列都至少有一个骨牌横跨.对\(10^9+7\)取模. \(n,m \leq 16\) 首先,这个问题的约 ...

  2. Luogu P2595 [ZJOI2009]多米诺骨牌 容斥,枚举,插头dp,轮廓线dp

    真的是个好(毒)题(瘤).其中枚举的思想尤其值得借鉴. \(40pts\):插头\(dp\),记录插头的同时记录每一列的连接状况,复杂度\(O(N*M*2^{n + m} )\). \(100pts\ ...

  3. 【题解】[HAOI2018]染色(NTT+容斥/二项式反演)

    [题解][HAOI2018]染色(NTT+容斥/二项式反演) 可以直接写出式子: \[ f(x)={m \choose x}n!{(\dfrac 1 {(Sx)!})}^x(m-x)^{n-Sx}\d ...

  4. 51Nod1518 稳定多米诺覆盖 动态规划 插头dp 容斥原理

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1518.html 题目传送门 - 51Nod1518 题意 51Nod真是个好OJ ,题意概括的真好, ...

  5. NOI Online 游戏 树形dp 广义容斥/二项式反演

    LINK:游戏 还是过于弱鸡 没看出来是个二项式反演,虽然学过一遍 但印象不深刻. 二项式反演:有两种形式 一种是以恰好和至多的转换 一种是恰好和至少得转换. 设\(f_i\)表示至多的方案数 \(g ...

  6. 多米诺骨牌放置问题(状压DP)

    例题: 最近小A遇到了一个很有趣的问题: 现在有一个\(n\times m\)规格的桌面,我们希望用\(1 \times 2\)规格的多米诺骨牌将其覆盖. 例如,对于一个\(10 \times 11\ ...

  7. HDU5731 Solid Dominoes Tilings 状压dp+状压容斥

    题意:给定n,m的矩阵,就是求稳定的骨牌完美覆盖,也就是相邻的两行或者两列都至少有一个骨牌 分析:第一步: 如果是单单求骨牌完美覆盖,请先去学基础的插头dp(其实也是基础的状压dp)骨牌覆盖 hiho ...

  8. bzoj2669[cqoi2012]局部极小值 容斥+状压dp

    2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 774  Solved: 411[Submit][Status ...

  9. 51nod 1673 树有几多愁——虚树+状压DP

    题目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1673 建一个虚树. 一种贪心的想法是把较小的值填到叶子上,这样一个小值限制到的 ...

随机推荐

  1. 《图解设计模式》读书笔记4-2 STRATEGY模式

    目录 示例程序 角色 想法 Strategy模式即策略模式,在编程中,策略指的就是算法.利用此模式可以整体替换算法,即使用不同方式解决同一个问题.比如设计一个围棋程序,通过切换算法可以方便地切换AI的 ...

  2. Jenkins使用一:CentOS7安装Jenkins

    安装jdk环境: yum search jdk 装 1.8版本的:yum install -y java-1.8.0-openjdk 安装Jenkins wget -O /etc/yum.repos. ...

  3. CentOS 7命令行安装GNOME、KDE图形界面(成功安装验证)

    来源:cnblogs.com/Amedeo  作者:Amedeo 正文 CentOS 7 默认是没有图形化界面的,但我们很多人在习惯了 Windows 的图形化界面之后,总是希望有一个图形化界面从而方 ...

  4. 排序,其他的运用 os fork

    while True: str_num = input("Enter number:") flag = True dotCount = 0 if str_num[0] == '-' ...

  5. 06:(h5*)Vue第六天

    目录 1:iView 2:  element 3:  vuex 正文 1:i-view 1:装包 npm install view-design --save 2:导包 import ViewUI f ...

  6. TCP协议-流量控制

    流量控制是通过滑动窗口来实现控制的.使用了坚持定时器,防止发送失败导致死锁.

  7. [Bzoj1030][JSOI2007]文本生成器(AC自动机&dp)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1030 最最最常见的多串匹配问题!题目求至少包含一个子串的方案数,则可以转化成全部方案-不 ...

  8. [CF453C] Little Poney and Summer Sun Celebration (思维)

    [CF453C] Little Poney and Summer Sun Celebration (思维) 题面 给出一张N个点M条边的无向图,有些点要求经过奇数次,有些点要求经过偶数次,要求寻找一条 ...

  9. BZOJ 1109 (LIS)

    题面 传送门 分析 设dp[i]是第i个积木在自己的位置上时,前i个积木中最多能回到自己位置的数目. \(dp[i]=max(dp[j])+1 (i>j,a[i]>a[j],a[i]-a[ ...

  10. python学习第十六天集合的关系测试

    在做数据分析的时候,要对一个集合分析,而且分析多个集合的之间的关系分析,那么用传统的循环的比较麻烦,集合提供很多方法,很容易比较多个集合的关系,并集,交集,差集,对称差集等. n1={1,2,4,6} ...