状压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) << "
"
43 #define endl "
"
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
",ans); 
89     }
90     return 0;
91 }
View Code

没有预处理

#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) << "
"
#define endl "
"
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
",ans); 
    }
    return 0;
}  
原文地址:https://www.cnblogs.com/klaycf/p/9598156.html