状压DP
牧场的安排
:将每行输入的数字转换为十进制,然后预处理出所有满足题意的状态并存储于 sta ,再处理出单独一行时候的方案数并存储于 dp1,sta 枚举第 i 行的状态,判断第 j = i-1行的状态,并更新dpi , j ,最后累和即可
#include <bits/stdc++.h> using namespace std; #define ll long long using namespace std; const int mod = 1e8;/// 998244353; const int mxn = 15 +7; ll _,m,n,t,k,ans; int dp[mxn][1<<13] , a[mxn][mxn] , f[mxn] , sta[1<<13] ; void solve() { while(cin>>m>>n){ memset(f,0,sizeof(f)); memset(sta,0,sizeof(sta)); memset(dp,0,sizeof(dp)); for(int i=1;i<=m;i++){ /// for(int j=1;j<=n;j++){ cin>>a[i][j]; f[i] = (f[i]<<1) + a[i][j]; } } ll last = (1<<n); for(int i=0;i<last;i++){ /// if(( (i&(i<<1))==0) && ((i&(i>>1))==0) ) sta[i] = 1 ; } for(int i=0;i<last;i++){/// 状态合理 , 输入满足状态 if(sta[i]==1 && ( (i&f[1]) ==i ) ) dp[1][i] = 1 ; } for(int i=2;i<=m;i++){ for(int j=0;j<last;j++){ if(sta[j]==1 && ( (f[i] & j) == j) ){ for(int k=0;k<last;k++) /// i-1 行状态 if((j&k)==0) dp[i][j] = (dp[i][j]+dp[i-1][k])%mod; } } } ans = 0 ; for(int i=0;i<last;i++) ans = (ans+dp[m][i])%mod; cout<<ans<<endl; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); solve(); }
所遇皆星河