状态压缩dp_学习笔记

1.AcWing 291.蒙德里安的梦想

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int N=12,M= 1 << N;
int n,m;
ll dp[N][M];
vector<int> state[M];
bool st[M];
int main(){
    while(cin>>n>>m,n||m){
        for(int i=0;i<(1<<n);i++){
            int cnt=0;
            bool is_valid=true;
            for(int j=0;j<n;j++){
                if((i>>j)&1){
                    if(cnt&1){
                        is_valid=false;
                        break;
                    }
                    cnt=0;
                }
                else
                    cnt++;
            }
            if(cnt&1) is_valid=false;
            st[i]=is_valid;            
        }
        for(int i=0;i<(1<<n);i++){
            state[i].clear();
            for(int j=0;j<(1<<n);j++){
                if((i&j)==0&&st[i|j]){
                    state[i].pb(j);
                }
            }
        }
        mem(dp,0);
        dp[0][0]=1;
        for(int i=1;i<=m;i++){
            for(int j=0;j<(1<<n);j++){
                for(auto k:state[j]){
                    dp[i][j]+=dp[i-1][k];
                }
            }
        }
        cout<<dp[m][0]<<endl;
    }
}
View Code

 2.AcWing 1064.小国王

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
const int N=12,M = 1 << 10,K=110;
int n,m,cnt[M];ll dp[N][K][M];
vector<int> state;
vector<int> head[M];
bool judge(int x){
    for(int i=0;i<n;i++){
        if(((1<<i)&x)&&((1<<(i+1))&x)){
            return false;
        }
    }
    return true;
}
int count(int x){
    int cnt=0;
    for(int i=0;i<n;i++){
        if((1<<i)&x) cnt++;
    }
    return cnt;
}
int main(){
    cin>>n>>m;
    for(int i=0;i<(1<<n);i++){
        if(judge(i)){
            state.pb(i);
            cnt[i]=count(i);
        }
    }
    for(int i=0;i<state.size();i++){
        for(int j=0;j<state.size();j++){
            int a=state[i],b=state[j];
            if((a&b)==0&&judge(a|b)){
                head[i].pb(j);
            }    
        }
    }
    dp[0][0][0]=1;
    for(int i=1;i<=n+1;i++){
        for(int j=0;j<=m;j++){
            for(int a=0;a<state.size();a++){
                for(auto b:head[a]){
                    int c=cnt[state[a]];
                    if(j>=c){
                        dp[i][j][a]+=dp[i-1][j-c][b];
                    }
                }
            }
        }
    }
    cout<<dp[n+1][m][0]<<endl;
}
View Code

 3.AcWing 372.玉米田

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e8;
const int maxn=1e5+5;
const int N=13,M = 1 << 13;
int n,m;ll dp[N][M];
int g[M];
vector<int> state;
vector<int> head[M];
bool judge(int x){
    for(int i=0;i<m;i++){
        if(((1<<i)&x)&&((1<<(i+1))&x)){
            return false;
        }
    }
    return true;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=0;j<m;j++){
            int x;cin>>x;
            g[i]+=(!x)<<j;
        }
    }
    for(int i=0;i<(1<<m);i++){
        if(judge(i)) state.pb(i);
    }
    for(int i=0;i<state.size();i++){
        for(int j=0;j<state.size();j++){
            int a=state[i],b=state[j];
            if((a&b)==0){
                head[i].pb(j);
            }
        }
    }
    dp[0][0]=1;
    for(int i=1;i<=n+1;i++){
        for(int a=0;a<state.size();a++){
            for(auto b:head[a]){
                if(g[i]&state[a]) continue;
                dp[i][a]=(dp[i][a]+dp[i-1][b])%mod;
            }
        }
    }
    cout<<dp[n+1][0]<<endl;
}
View Code

 4.AcWing 292.炮兵阵地

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
const int N=10,M=1 << 10;
int g[1050],dp[2][M][M];
vector<int> state;
int cnt[M],n,m;
bool check(int x){
    for(int i=0;i<m;i++){
        if(((1<<i)&x)&&(((1<<i+1)&x)||((1<<i+2)&x))) return false;
    }
    return true;
}
int count(int x){
    int cnt=0;
    for(int i=0;i<m;i++){
        if(1<<i&x) cnt+=1;
    }
    return cnt;
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=0;j<m;j++){
            char c;cin>>c;
            g[i]+=(c=='H')<<j;
        }
    }
    for(int i=0;i<1<<m;i++){
        if(check(i)){
            state.pb(i);
            cnt[i]=count(i);
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=0;j<state.size();j++){
            for(int k=0;k<state.size();k++){
                for(int u=0;u<state.size();u++){
                    int a=state[j],b=state[k],c=state[u];
                    if(a&b|a&c|b&c) continue;
                    if(g[i]&b|g[i-1]&a|g[i-2]&c) continue;
                    dp[i&1][j][k]=max(dp[i&1][j][k],dp[i-1&1][u][j]+cnt[b]);
                }
            }
        }
    }
    int res=0;
    for(int i=0;i<state.size();i++){
        for(int j=0;j<state.size();j++){
            res=max(res,dp[n&1][i][j]);
        }
    }
    cout<<res<<endl;
}
View Code

 5.AcWIng 91.最短Hamilton路径

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define ll long long
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,n,a) for(int i=n;i>=a;i--)
#define endl '
'
#define eps 0.000000001
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define IO ios::sync_with_stdio(false);cin.tie(0);
using namespace std;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+7;
const int maxn=1e5+5;
const int N=20,M=1<<N;
int n;
int dp[M][N],w[N][N];
int main(){
    cin>>n;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
            cin>>w[i][j];
    mem(dp,INF);
    dp[1][0]=0;
    for(int i=0;i<(1<<n);i++){
        for(int j=0;j<n;j++){
            if(i>>j&1){
                for(int k=0;k<n;k++){
                    if(i>>k&1){
                        dp[i][j]=min(dp[i][j],dp[i-(1<<j)][k]+w[k][j]);
                    }
                }
            }
        }
    }
    cout<<dp[(1<<n)-1][n-1]<<endl;
    return 0;        
}
View Code
原文地址:https://www.cnblogs.com/Anonytt/p/13470195.html