Describe
题目链接
给一个$M\times N$的矩阵,矩阵每个位置为$0/1$,问选一些$1$使这些不相邻的方案数。
Solution
明显状压$DP$。
那么怎么$DP$呢?
设$f[i][j]$表示第$i$行状态为$j$的方案数。
那么转移就可以暴力枚举上一行的状态再判断可能性转移。
$$f[i][j]+=f[i-1][k]$$
那么怎么判断是否可行呢?
$!j\&(j<<1)\&\&!j\&(j>>1)$表示同一行两个相邻的不能同被选择。
直观感受
那么还有什么条件呢?$S[i]\&j\text{^}j$即这个状态必须选择的都是$1$。$!j\&k$即和上一行不要重复。
那么就直接上代码(逃:
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include<bits/stdc++.h> #define mod 100000000 using namespace std; int m,n,S[20],f[20][(1<<13)+10],ans; int main(){ cin>>m>>n; for(int i=1;i<=m;i++) for(int x,j=1;j<=n;j++) cin>>x,S[i]=S[i]<<1x; f[0][0]=1; for(int i=1;i<=m;i++){ for(int j=0;j<(1<<n);j++){ if(j&(j<<1)j&(j>>1)S[i]&j^j) continue ; for(int k=0;k<(1<<n);k++){ if(k&j) continue ; f[i][j]+=f[i-1][k]; f[i][j]%=mod; } } } for(int i=0;i<(1<<n);i++) ans+=f[m][i],ans%=mod; cout<<ans<<endl; }
|