炮兵阵地 POJ

来源:互联网 发布:2012nba总决赛数据 编辑:程序博客网 时间:2024/05/16 08:10

点击打开链接

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

其中dp[i][j][k]代表 第i行在状态k下 第i-1行在状态j下共可放多少炮台 cnt[k]代表状态k下该行有多少炮台

对于每一行 枚举上上行 上行 和当前行 若三行状态互不冲突 且与地形不冲突 则转移状态有效

#include <stdio.h>#include <cstring>#include <algorithm>using namespace std;int dp[110][110][110];int sta[110],cnt[110],pre[110];int n,m,sum,ans;void init(){    int i,t;    sum=0;    for(i=0;i<(1<<10);i++)    {        if(i&(i<<1)||i&(i<<2)) continue;        sta[sum]=i;        t=i;        while(t>0)        {            cnt[sum]+=t%2;            t/=2;        }        sum++;    }    return;}int judge(int x,int y){    if(x&y) return 0;return 1;}void calculate(){    int i,j,k,l;    memset(dp,0,sizeof(dp));    ans=0;    for(i=0;i<sum;i++)    {        if(judge(pre[1],sta[i]))        {            dp[1][0][i]=cnt[i];            ans=max(ans,cnt[i]);        }    }    for(i=2;i<=n;i++)    {        for(j=0;j<sum;j++)        {            for(k=0;k<sum;k++)            {                for(l=0;l<sum;l++)                {                    if(judge(sta[j],sta[k])&&judge(sta[k],sta[l])&&judge(sta[l],sta[j])&&judge(pre[i],sta[k])&&judge(pre[i-1],sta[j])&&judge(pre[i-2],sta[l])&&dp[i-1][l][j]!=0)                    {                        dp[i][j][k]=max(dp[i][j][k],dp[i-1][l][j]+cnt[k]);                        ans=max(ans,dp[i][j][k]);                    }                }            }        }    }    return;}int main(){    int i,j;    char ch[20];    init();    while(scanf("%d%d",&n,&m)!=EOF)    {        memset(pre,0,sizeof(pre));        sum=0;        for(i=0;i<(1<<m);i++)        {            if(!(i&(i<<1)||i&(i<<2))) sum++;        }        for(i=1;i<=n;i++)        {            scanf("%s",ch);            for(j=0;j<m;j++)            {                if(ch[j]=='H')                {                    pre[i]+=(1<<j);                }            }        }        calculate();        printf("%d\n",ans);    }    return 0;}

原创粉丝点击