突然想到这么一个词语,觉得很重要。
最近在看状态压缩dp,因为不会状压,所以还找了那个ppt去看,外面又百度看了几篇博客,感受一下那个写法。我自己第一道状态压缩dp,之前自己写的深搜是这种的:
void dfs(int cur,int st,int count) { if(cur==m) { state[tot]=st; stanum[tot++]=count; return; } flg[cur+1]=0; dfs(cur+1,st<<1,count); if(flg[cur-1]+flg[cur]==0) { flg[cur+1]=1; dfs(cur+1,st<<1|1,count+1); } }
后来又改了一下,我自己觉得没什么问题,因为的确有对拍过,可是不知道就是哪里不对。。
void dfs(int cur,int st,int count) { if(cur==m) { state[tot]=st; stanum[tot++]=count; return; } flg[cur+1]=0; dfs(cur+1,st<<1,count); if(cur<1) { flg[cur+1]=1; dfs(cur+1,st<<1|1,count+1); } else { if(flg[cur-1]+flg[cur]==0) { flg[cur+1]=1; dfs(cur+1,st<<1|1,count+1); } } }
完整代码:
#include <algorithm> #include <iostream> #include <cstdlib> #include <cstring> #include <cstdio> #include <queue> using namespace std; const int maxn=100+5; const int maxm=10+5; int n,m,tot; int state[65],stanum[65]; int in[maxn]; bool flg[maxm]; //char s[maxn][maxm]; void dfs(int cur,int st,int count) { if(cur==m) { state[tot]=st; stanum[tot++]=count; return; } flg[cur+1]=0; dfs(cur+1,st<<1,count); if(cur<1) { flg[cur+1]=1; dfs(cur+1,st<<1|1,count+1); } else { if(flg[cur-1]+flg[cur]==0) { flg[cur+1]=1; dfs(cur+1,st<<1|1,count+1); } } } void init() { tot=0; dfs(0,0,0); } void data_in() { char tmp; for(int i=1;i<=n;i++) { in[i]=0; getchar(); for(int j=1;j<=m;j++) { scanf("%c",&tmp); // s[i][j]=tmp; in[i]=in[i]*2+(tmp=='H'?1:0); } } } int dp[2][65][65]; void DP() { memset(dp,-1,sizeof(dp)); for(int i=0;i<tot;i++) { if(in[1]&state[i]) continue; dp[1][i][0]=stanum[i]; } int now=1; for(int i=2;i<=n;i++) { now^=1; for(int j=0;j<tot;j++) { if(in[i]&state[j]) continue; else for(int k=0;k<tot;k++) { if(state[j]&state[k]) continue; else for(int l=0;l<tot;l++) { if(state[j]&state[l]) continue; else if(dp[now^1][k][l]==-1) continue; else dp[now][j][k]=max(dp[now][j][k],dp[now^1][k][l]+stanum[j]); } } } } int ans=0; for(int i=0;i<tot;i++) { for(int j=0;j<tot;j++) ans=max(ans,dp[now][i][j]); } printf("%d\n",ans); } int main() { while(~scanf("%d %d",&n,&m)) { init(); data_in(); DP(); } return 0; }