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;
}
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号