炮兵阵地[状态压缩DP]

看到这一道题其实和玉米田很类似,只不过多记录了前两行,其他大体细节差不多,注意滚动数组似乎不滚动更快???


Code

#include<bits/stdc++.h>
using namespace std;
const int N=105;
struct state{
    int num[105],a[105];
}st[105];
int n,m;
char s[15];
int f[3][105][105];
void getstate(int k,char *s){
    int t=0;
    for(int i=1;i<=m;i++){
        t<<=1;
        if(s[i]=='H')
         t++;
    }
    for(int i=0;i<(1<<m);i++){
        if((i&(i<<1))||(i&(i>>1))||(i&(i<<2))||(i&(i>>2))||(i&t))
         continue;
        st[k].a[++st[k].a[0]]=i;
        for(int j=1;j<=(1<<m);j<<=1)
         if(i&j)++st[k].num[st[k].a[0]];
    }
}
inline void dp(){
    memset(f,-0x3f,sizeof(f));
    f[0][0][0]=0;
    for(int j=1;j<=st[1].a[0];j++)
     f[1][j][0]=st[1].num[j];
    for(int i=1;i<=st[2].a[0];i++)
     for(int j=1;j<=st[1].a[0];j++)
      if(!(st[2].a[i]&st[1].a[j]))
       f[2][i][j]=max(f[2][i][j],f[1][j][0]+st[2].num[i]);
    for(int i=3;i<=n;i++)
     for(int j=1;j<=st[i].a[0];j++)
      for(int k=1;k<=st[i-1].a[0];k++)
       if(!(st[i].a[j]&st[i-1].a[k])){
            for(int l=1;l<=st[i-2].a[0];l++)
          if(!(st[i].a[j]&st[i-2].a[l])) 
           f[i%3][j][k]=max(f[i%3][j][k],f[(i-1)%3][k][l]+st[i].num[j]);
       }
    int ans=-0x3f;
    for(int i=1;i<=st[n].a[0];i++)
     for(int j=1;j<=st[n-1].a[0];j++)
      if(!(st[n].a[i]&st[n-1].a[j]))
      ans=max(ans,f[n%3][i][j]);
    cout<<ans<<endl;
}
int main(){
    scanf("%d %d ",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s", s+1);
        getstate(i,s);
    }
    dp();
    return 0;
}

 

posted @ 2019-08-24 21:50  Coder_cjh  阅读(216)  评论(0编辑  收藏  举报