状压dp之不相连块
一块田里草地格子不能相邻,问有几种方案。
预处理不相邻块
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstring> 6 #include<map> 7 #include<set> 8 #include<queue> 9 #include<bitset> 10 #include<utility> 11 #include<functional> 12 #include<iomanip> 13 #include<sstream> 14 #include<ctime> 15 #include<cassert> 16 #define A first 17 #define B second 18 #define mp make_pair 19 #define pb push_back 20 #define pw(x) (1ll << (x)) 21 #define sz(x) ((int)(x).size()) 22 #define all(x) (x).begin(),(x).end() 23 #define rep(i,l,r) for(int i=(l);i<(r);i++) 24 #define per(i,r,l) for(int i=(r);i>=(l);i--) 25 #define FOR(i,l,r) for(int i=(l);i<=(r);i++) 26 #define eps 1e-9 27 #define PIE acos(-1) 28 #define cl(a,b) memset(a,b,sizeof(a)) 29 #define fastio ios::sync_with_stdio(false);cin.tie(0); 30 #define lson l , mid , ls 31 #define rson mid + 1 , r , rs 32 #define ls (rt<<1) 33 #define rs (ls|1) 34 #define INF 0x3f3f3f3f 35 #define lowbit(x) (x&(-x)) 36 #define sqr(a) a*a 37 #define ll long long 38 #define ull unsigned long long 39 #define vi vector<int> 40 #define pii pair<int, int> 41 #define dd(x) cout << #x << " = " << (x) << ", " 42 #define de(x) cout << #x << " = " << (x) << "\n" 43 #define endl "\n" 44 using namespace std; 45 //********************************** 46 const int mod=1e9; 47 int n,m; 48 const int maxn=510; 49 bool a[15][15]; 50 int dp[15][maxn]; 51 int v[maxn]; 52 //********************************** 53 void Init() 54 { 55 int tot=0; 56 rep(i,0,1<<12){ 57 // dd(i);de(i&i<<1); 58 if((i&(i<<1))==0)v[tot++]=i;//注意加括号 59 } 60 } 61 bool check(int row,int st) 62 { 63 FOR(i,1,m){ 64 if((st&(1<<i-1))&&!a[row][i])return false; 65 } 66 return true; 67 } 68 inline int add(int a,int b){if((a+=b)>mod)a-=mod;return a;} 69 //********************************** 70 int main() 71 { 72 Init(); 73 while(~scanf("%d%d",&n,&m)){ 74 cl(dp,0); 75 FOR(i,1,n)FOR(j,1,m)scanf("%d",&a[i][j]); 76 FOR(i,1,n){//row 77 for(int j=0;v[j]<(1<<m);j++){ 78 if(!check(i,v[j]))continue; 79 if(i==1)dp[i][j]=1; 80 else { 81 for(int k=0;v[k]<(1<<m);k++)if((v[j]&v[k])==0)dp[i][j]=add(dp[i][j],dp[i-1][k]); 82 } 83 } 84 } 85 86 int ans=0; 87 for(int i=0;v[i]<(1<<m);i++)ans=add(ans,dp[n][i]); 88 printf("%d\n",ans); 89 } 90 return 0; 91 }
没有预处理
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<cstring> #include<map> #include<set> #include<queue> #include<bitset> #include<utility> #include<functional> #include<iomanip> #include<sstream> #include<ctime> #include<cassert> #define A first #define B second #define mp make_pair #define pb push_back #define pw(x) (1ll << (x)) #define sz(x) ((int)(x).size()) #define all(x) (x).begin(),(x).end() #define rep(i,l,r) for(int i=(l);i<(r);i++) #define per(i,r,l) for(int i=(r);i>=(l);i--) #define FOR(i,l,r) for(int i=(l);i<=(r);i++) #define eps 1e-9 #define PIE acos(-1) #define cl(a,b) memset(a,b,sizeof(a)) #define fastio ios::sync_with_stdio(false);cin.tie(0); #define lson l , mid , ls #define rson mid + 1 , r , rs #define ls (rt<<1) #define rs (ls|1) #define INF 0x3f3f3f3f #define lowbit(x) (x&(-x)) #define sqr(a) a*a #define ll long long #define ull unsigned long long #define vi vector<int> #define pii pair<int, int> #define dd(x) cout << #x << " = " << (x) << ", " #define de(x) cout << #x << " = " << (x) << "\n" #define endl "\n" using namespace std; //********************************** const int mod=1e9; int n,m; const int maxn=1<<12; bool a[15][15]; int dp[15][maxn]; int v[maxn]; //********************************** bool check(int row,int st) { if((st&(st<<1)))return false; FOR(i,1,m){ if((st&(1<<i-1))&&!a[row][i])return false; } return true; } inline int add(int a,int b){if((a+=b)>mod)a-=mod;return a;} //********************************** int main() { while(~scanf("%d%d",&n,&m)){ cl(dp,0); FOR(i,1,n)FOR(j,1,m)scanf("%d",&a[i][j]); FOR(i,1,n){//row rep(mask,0,1<<m){ if(!check(i,mask))continue; if(i==1)dp[i][mask]=1; else { //判断与上一行的草地有没有相邻 rep(k,0,1<<m)if((mask&k)==0)dp[i][mask]=add(dp[i][mask],dp[i-1][k]); } } } int ans=0; rep(mask,0,1<<m)ans=add(ans,dp[n][mask]); printf("%d\n",ans); } return 0; }