[传送门[(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. LeetCode 337. House Robber III 动态演示

    每个节点是个房间,数值代表钱.小偷偷里面的钱,不能偷连续的房间,至少要隔一个.问最多能偷多少钱 TreeNode* cur mp[{cur, true}]表示以cur为根的树,最多能偷的钱 mp[{c ...

  2. hdu2602Bone Collector ——动态规划(0/1背包问题)

    Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collec ...

  3. spring事务——try{...}catch{...}中事务不回滚的几种处理方式(转载)

    转载自   spring事务——try{...}catch{...}中事务不回滚的几种处理方式   当希望在某个方法中添加事务时,我们常常在方法头上添加@Transactional注解 @Respon ...

  4. 什么是php工厂模式

    工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式.著名的Jive论坛 ,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见.今天我们就为大家介绍一下PHP中的 ...

  5. LayUI Table复杂表头实现

    LayUI table官方文档中在介绍复杂表头时的用例仅使用了自动渲染的方式作为参考,而并未用到方法渲染的方式来做用例,这让部分不太熟悉layUI table的开发者会有些头疼,不知道如何在方法渲染中 ...

  6. Spring数据库连接池 c3p0、dbcp、spring-jdbc

    在用dbcp的时候 后面加上 destroy-method="close" 销毁的方法没事 但是用 spring的jdbc就会报错 提示找不到close这个方法  这是为什么? D ...

  7. POJ 3764 The xor-longest Path (01字典树)

    <题目链接> 题目大意: 给定一颗$n$个节点$(n\leq10^5)$,有边权的树,其边权$(0\leq w < 2^{31})$.让你求出这棵树上任意两个节点之间的异或最大值. ...

  8. 从0构建webpack开发环境(二) 添加css,img的模块化支持

    在一个简单的webpack.config.js中,构建了一个基础的webpack.config.js文件,但是只支持js模块的打包. 本篇中添加对css和img的模块化支持 首先需要安装三个个load ...

  9. Cheatsheet: 2019 03.01 ~ 04.30

    Golang How To Install Go and Set Up a Local Programming Environment on macOS Build A Go API 40+ prac ...

  10. redis限流器的设计

    1.定义注解 import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java. ...