POJ 1185 炮兵阵地

擦,真不应该让这个题目弄这么久

就是一个比较简单的状态DP,先预处理出每一行的可行情况,然后因为当前行是和前两行有关系的,果断不能只用个两维啊,我一开始Dp数组开个两维,只记录当前行的状态,结果在枚举前面行的时候果断就不行啊,因为你枚举了上一行那上一行的前两行又要枚举,果断不行啊,我居然还照着这个思路全部写完并且过了样例,还提交WA了很久都没反应过来

至少开三维,dp[i][j][k]记录当前行为j状态,i-1行为k状态时的最大值,那么dp[i][j][k]=max(本身,dp[i-1][k][w]+cot[j]),其中状态和某个状态的含1的个数都预处理好了,j,k,w

都是状态编号,w为i-2行的状态,cot记录某状态的1的个数,这样就果断不会漏情况了啊

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int ma[105];
int dp[110][105][105];
int sum;
int test[1<<11],cot[1<<11];
int num;
int m,n;
bool ok(int sta1,int sta)
{
    //if ((sta&(sta<<1)) || (sta & (sta<<2))) return 0;
    if (sta & sta1)
        return 0;
    return 1;
}

void  init()
{
    int all=1<<m;
    num=0;
    for (int i=0;i<all;i++)
    {
        if (i&(i<<1) || i&(i<<2))
            continue;
        test[num]=i;
        int tmp=i,tc=0;
        while (tmp)
        {
            tc++;
            tmp&=tmp-1;
        }
        cot[num++]=tc;
    }
}
int main()
{
    char ch[15];
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        init();
        memset(dp,0,sizeof dp);
        for (int i=1; i<=n; i++)
        {
            scanf("%s",ch);
            //puts(ch);
            ma[i]=0;
            for (int j=0; j<m; j++)
            {
                if (ch[j]=='H')
                    ma[i]|=1<<j;
            }
        }
        sum=0;
        for (int i=0; i<num; i++)
        {
            if (ok(ma[1],test[i])==0) continue;
            dp[1][i][0]=cot[i];
            sum=max(sum,dp[1][i][0]);
        }
        for (int i=2; i<=n; i++)
            for (int j=0; j<num; j++){
              if (!ok(test[j],ma[i])) continue;
              for (int k=0;k<num;k++)
              {
                  if (!ok(test[j],test[k])|| !ok(test[k],ma[i-1]))
                  continue;
                  for (int w=0;w<num;w++)
                  {
                      if (!ok(test[w],ma[i-2])) continue;
                      if (!ok(test[w],test[j])||!ok(test[w],test[k])) continue;
                      if (dp[i-1][k][w]==0) continue;
                      dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][w]+cot[j]);
                      sum=max(sum,dp[i][j][k]);
                  }
              }
            }

        printf("%d\n",sum);
    }
    return 0;
}

 

posted @ 2014-04-01 13:52  KRisen  阅读(240)  评论(0编辑  收藏  举报