Problem:
题目
Solution:
状压dp,注意:
(1)当前行状态和题中状态冲突
(2)当前状态中出现两个相邻的 1
(3)上一行与当前行状态冲突(上下同时出现 1)
#include<bits/stdc++.h> #define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define _for(i,s,t) for(int i=s;i<t;i++) #define _rof(i,s,t) for(int i=s;i>t;i--) #define rep(i,s,t) for(int i=s;i<=t;i++) #define per(i,s,t) for(int i=s;i>=t;i--) #define Ri(x) scanf("%d",&x) #define Rii(x,y) scanf("%d%d",&x,&y) #define INF 0x3f3f3f3f using namespace std; template<class T>inline void read(T &res) { char c;T flag=1; while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; } typedef long long ll; const int maxn = 1e1 + 10; const int mod = 100000000; int stat[maxn],dp[maxn][1 << 13]; int main(){ IOS; int n,m,v; while(cin>>n>>m){ memset(stat,0,sizeof mp); memset(dp,0,sizeof dp); rep(i,1,n){ _for(j,0,m){ cin>>v; stat[i] |= (v << j); } // cout<<stat[i]<<endl; } dp[0][0] = 1; rep(i,1,n){// 枚举行 _for(j,0,(1 << m)){// 枚举当前行状态 if((j | stat[i]) != stat[i]){// 当前行状态和题中状态冲突 continue; } if(j & (j >> 1)){// 当前状态中出现两个相邻的 1 continue; } _for(k,0,(1 << m)){// 枚举上一行 if(k & j){// 上一行与当前行状态冲突(上下同时出现 1) continue; } dp[i][j] += dp[i - 1][k]; dp[i][j] %= mod; } } } int ans = 0; _for(i,0,(1 << m)){ ans += dp[n][i]; ans %= mod; } cout<<ans<<endl; } return 0; }