• 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
    ",sum);
        }
        return 0;
    }
  • 相关阅读:
    洛谷-P1427 小鱼的数字游戏
    洛谷-P1047 校门外的树
    洛谷-P1046 陶陶摘苹果
    洛谷-P1980 计数问题
    洛谷-P1424 小鱼的航程(改进版)
    洛谷-P1423 小玉在游泳
    洛谷-P1035 级数求和
    洛谷-P1008 三连击
    Oracle 11g r2 rac +openfiler 2.99 安装
    26 主备库并行复制策略
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3638128.html
Copyright © 2020-2023  润新知