状态压缩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 '\n' #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; } }
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 '\n' #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; }
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 '\n' #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; }
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 '\n' #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; }
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 '\n' #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; }
前ICPC算法竞赛退役选手|现摸鱼ing