• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
ACM s1124yy
守りたいものが 強くさせること
博客园    首页    新随笔    联系   管理     

POJ 1185 炮兵阵地(状态压缩DP)

题解:nState为状态数,state数组为可能的状态

代码:

#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

const int INF=0x3f3f3f3f;
typedef long long ll;
typedef unsigned long long ull;
#define fi first
#define se second
#define prN printf("\n")
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d%d",&(N),&(M))
#define SIII(N,M,K) scanf("%d%d%d",&(N),&(M),&(K))
#define cle(a,val) memset(a,(val),sizeof(a))
#define rep(i,b) for(int i=0;i<(b);i++)
#define Rep(i,a,b) for(int i=(a);i<=(b);i++)

int n,m,dp[105][80][80];
int row[105];
int nState,state[80],num[80];

void init()
{
    int k=1<<m;
    nState=0;
    rep(i,k)
    {
        if ((i&(i<<1))==0&&(i&(i<<2))==0)
        {
            state[nState]=i;
            num[nState]=0;
            int j=i;
            while(j)
            {
                num[nState]+=j%2;
                j/=2;
            }
            nState++;
        }
    }
}



int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:\\Users\\Zmy\\Desktop\\in.txt","r",stdin);
//    freopen("C:\\Users\\Zmy\\Desktop\\out.txt","w",stdout);
#endif // ONLINE_JUDGE

    char str[20]= {0};

    while(cin>>n>>m)
    {
        init();
        rep(i,n)
        {
            row[i]=0;
            scanf("%s",str);
            rep(j,m)
            {
                if (str[j]=='P')
                {
                    row[i]+=1<<j;
                }
            }
        }

        cle(dp,0);

        rep(j,nState)
        {
            if ((state[j]&row[0])!=state[j])
            {
                continue;
            }
            rep(k,nState)
            {
                dp[0][j][k]=num[j];
            }
        }

        if (n>1)
            rep(j,nState)
        {
            if ((state[j]&row[1])!=state[j])
            {
                continue;
            }
            rep(k,nState)//这的k代表的是上上个
            {
                if ((state[j]&state[k])==0)
                {
                    dp[1][j][k]=dp[0][k][0] + num[j];/**< 这是啥意思?? */
                }
            }
        }

        Rep(i,2,n-1)
        {
            rep(j,nState)
            {
                if ((state[j]&row[i])!=state[j])
                {
                    continue;
                }
                rep(k,nState)//这的k代表的是上上个
                {
                    if ( state[j] & state[k] )
                        continue;
                    for (int h = 0; h < nState; h++)/**< i是这个,j是上1,k是上2,h是上3 */
                    {
                        if ( state[j] & state[h] )
                            continue;
                        if ( dp[i-1][k][h] > dp[i][j][k] )
                            dp[i][j][k] = dp[i-1][k][h];
                    }
                    dp[i][j][k] += num[j];

                }
            }
        }
        int maxa = 0;
        for (int j = 0; j < nState; j++)
        {
            for (int k = 0; k < nState; k++)
                if (maxa < dp[n-1][j][k])
                    maxa = dp[n-1][j][k];
        }

        printf("%d\n", maxa);


    }

    return 0;
}

  

posted @ 2016-05-18 07:54  s1124yy  阅读(170)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3