状压dp基础总结
Posted pandaking
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了状压dp基础总结相关的知识,希望对你有一定的参考价值。
这篇博客是参照另一篇博客写的:这是另一个博客的地址:https://www.cnblogs.com/Ronald-MOK1426/p/8456945.html
首先我做过的几道题目:
poj1185 炮兵阵地:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define mem memset(a,0,sizoef(a)) 7 #define legal(a,b) a&b 8 int row,cow; 9 int base[110]; 10 int state[110]; 11 int dp[110][110][110]; 12 int soldier[110]; 13 char g[110][15]; 14 int nums=0; 15 int main(){ 16 scanf("%d%d",&row,&cow); 17 for(int i=0;i<row;i++){ 18 //for(int j=0;j<cow;j++) scanf("%c",&g[i][j]); 19 scanf("%s",g[i]); 20 for(int j=0;j<cow;j++) 21 if(g[i][j]==‘H‘) base[i]+=(1<<j); 22 } 23 24 for(int i=0;i<(1<<cow);i++){ 25 if(legal(i,i<<1)||legal(i,i<<2)) continue; 26 int k=i; 27 while(k){ 28 soldier[nums]+=(k&1); 29 k=k>>1; 30 } 31 state[nums++]=i; 32 } 33 34 for(int i=0;i<nums;i++){ 35 if(legal(state[i],base[0])) continue; 36 dp[0][i][0]=soldier[i]; 37 } 38 39 for(int r=1;r<row;r++){ 40 for(int i=0;i<nums;i++){ 41 if(legal(state[i],base[r])) continue; 42 for(int j=0;j<nums;j++){ 43 if(legal(state[j],base[r-1])) continue; 44 if(legal(state[i],state[j])) continue; 45 for(int k=0;k<nums;k++){ 46 if(legal(state[k],base[r-2])) continue; 47 if(legal(state[i],state[k])) continue; 48 if(legal(state[j],state[k])) continue; 49 dp[r][i][j]=max(dp[r][i][j],dp[r-1][j][k]+soldier[i]); 50 } 51 } 52 } 53 } 54 55 int ans=0; 56 for(int i=0;i<nums;i++){ 57 for(int j=0;j<nums;j++){ 58 ans=max(ans,dp[row-1][i][j]); 59 } 60 } 61 printf("%d ",ans); 62 return 0; 63 }
poj3311
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int dis[15][15],maps[15][15]; 7 int dp[1<<15][15]; 8 int n; 9 int main(){ 10 while(scanf("%d",&n)!=EOF){ 11 if(n==0) break; 12 13 for(int i=0;i<=n;i++){ 14 for(int j=0;j<=n;j++){ 15 scanf("%d",&maps[i][j]); 16 dis[i][j]=maps[i][j]; 17 } 18 } 19 for(int k=0;k<=n;k++){ 20 for(int i=0;i<=n;i++){ 21 for(int j=0;j<=n;j++){ 22 if(dis[i][j]>dis[i][k]+maps[k][j]) 23 dis[i][j]=dis[i][k]+maps[k][j]; 24 } 25 } 26 } 27 28 memset(dp,-1,sizeof(dp)); 29 dp[1][0]=0; 30 for(int i=1;i<(1<<(n+1));i++){ 31 i=i|1; 32 for(int j=0;j<=n;j++){ 33 if(dp[i][j]!=-1){ 34 for(int k=0;k<=n;k++){ 35 if(j!=k&&(dp[(1<<k)|i][k]==-1||dp[(1<<k)|i][k]>dp[i][j]+dis[j][k])) 36 dp[(1<<k)|i][k]=dp[i][j]+dis[j][k]; 37 } 38 } 39 } 40 } 41 cout<<dp[(1<<(n+1))-1][0]<<endl; 42 } 43 return 0; 44 }
以上是关于状压dp基础总结的主要内容,如果未能解决你的问题,请参考以下文章
18.06.03 POJ 4126:DNA 15年程设期末05(状压DP)