状压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 }
View Code

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 }
View Code

 

以上是关于状压dp基础总结的主要内容,如果未能解决你的问题,请参考以下文章

[DP总结]状压DP

基础DP总结

18.06.03 POJ 4126:DNA 15年程设期末05(状压DP)

状压DP总结

POJ1699 Best Sequence(AC自动机+状压DP)

状压DP初探·总结