POJ 1185 炮兵阵地

状态压缩dp。

一开始想开个dp[2][1024][1024]的数组,显然开不下,而且也会超时。

因此把状态对应放在另外一个数组s里。

map[i]表示用二进制表示第i行的地势情况,1是高地,0是平原。

用dp[i][j][k]表示第i行,达到状态s[j],且i-1行的状态是s[k]的最优解。

状态转移方程为 dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][p]+cnt[j]);

满足状态转移方程的条件是 s[j]&map[i]==0,s[j]&s[k]==0,s[j]&s[p]==0,且dp[i-1][k][p]存在。

 

 

//Memory:228K
//Time:422ms


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int n,m;
int map[110];
int dp[2][110][110];
int s[110],scnt,cnt[110];

void DFS(int dta,int dep)
{
    bool ok=1;
    if(10==dep) {
        s[scnt++]=dta;
        return;
    }
    if(dep) {
        if((1<<(dep-1))&dta)
            ok=0;
        if(dep>1) {
            if((1<<(dep-2))&dta)
                ok=0;
        }
    }
    if(ok) DFS(dta|(1<<dep),dep+1);
    DFS(dta,dep+1);
}

void init()
{
    DFS(0,0);
    sort(s,s+scnt);
    s[scnt]=0x3f3f3f3f;
    for(int i=0;i<scnt;++i) {
        cnt[i]=0;
        for(int j=0;j<10;++j)
            if((1<<j)&s[i]) ++cnt[i];
    }
}

int main()
{
    init();
    char str[12];
    int hehe;
    int now,before;
    int ans;
    while(scanf("%d%d",&n,&m)==2) {
        memset(map,0,sizeof map);
        memset(dp,-1,sizeof dp);
        dp[0][0][0]=0;
        for(int i=1;i<=n;++i) {
            scanf("%s",str);
            for(int j=0;j<m;++j)
                if(str[j]=='H') map[i]|=(1<<(m-j-1));
        }
        hehe=1<<m;
        for(int i=1;i<=n;++i) {
            now=i&1;
            before=now?0:1;
            for(int j=0;s[j]<hehe;++j) {
                if(s[j]&map[i]) continue;
                for(int k=0;s[k]<hehe;++k) {
                    if(s[j]&s[k]) continue;
                    dp[now][j][k]=0;
                    for(int p=0;s[p]<hehe;++p) {
                        if(s[j]&s[p]||dp[before][k][p]==-1) continue;
                        dp[now][j][k]=max(dp[now][j][k],dp[before][k][p]+cnt[j]);
                    }
                }
            }
        }
        ans=0;
        for(int i=0;s[i]<hehe;++i) {
            for(int j=0;s[j]<hehe;++j)
                ans=max(ans,dp[now][i][j]);
        }
        printf("%d\n",ans);
    }
}

 

posted @ 2013-10-24 01:13  MoriMiya  Views(208)  Comments(0Edit  收藏  举报