hdu 4539(状态压缩dp)

题意:曼哈顿距离是指:|x1-x2|+|y1-y2|,只要知道这个概念题意就懂了。

分析:这道题与前面做的几道题有所不同,因为当前行不仅与前一行有关,而且与前两行有关,所以我们开数组的时候还要记录前两行的状态,所以我们需要开设三维数组。

代码实现:

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

int n,m,a[105];
int dp[2][202][202],st[202],num,b[202];

int suan(int x)
{
    int sum=0,i;
    for(i=1; i<=10; i++)
    {
        if((x&1))
            sum++;
        x=x>>1;
    }
    return sum;
}

void chushihua()
{
    int i,max=1<<10;
    for(i=0; i<max; i++)
     if((i&(i<<2))==0&&(i&(i>>2))==0)
     {
        st[num]=i;
        b[num++]=suan(i);
     }
}

void solve()
{
    int i,j,k,l,p=1,max=1<<m,res=0,temp;
    memset(dp,0,sizeof(dp));
    if(n>=1)
    for(i=0; i<num&&st[i]<max; i++)
    {
        if((a[1]&st[i])!=st[i])
            continue;
        temp=b[i];
        dp[1][0][i]=temp;
    }
    if(n>1)
    {
        p=p^1;
        for(i=0; i<num&&st[i]<max; i++)
        {
            if((a[2]&st[i])!=st[i])
                continue;
            temp=b[i];
            for(j=0; j<num&&st[j]<max; j++)
            {
                if((a[1]&st[j])!=st[j])
                    continue;
                if((st[i]&(st[j]<<1))!=0||(st[i]&(st[j]>>1))!=0)
                    continue;
                if(dp[0][j][i]<dp[1][0][j]+temp)
                    dp[0][j][i]=dp[1][0][j]+temp;
            }
        }
        for(i=3; i<=n; i++)
        {
            p=p^1;
            for(j=0; j<num&&st[j]<max; j++)
            {
                if((a[i]&st[j])!=st[j])
                    continue;
                temp=b[j];
                for(k=0; k<num&&st[k]<max; k++)
                {
                    if((st[j]&(st[k]<<1))!=0||(st[j]&(st[k]>>1))!=0)
                        continue;
                    if((a[i-1]&st[k])!=st[k])
                        continue;
                    for(l=0; l<num&&st[l]<max; l++)
                    {
                        if((a[i-2]&st[l])!=st[l])
                            continue;
                        if((st[k]&(st[l]<<1))!=0||(st[k]&(st[l]>>1))!=0)
                            continue;
                        if((st[l]&st[j])!=0)
                            continue;
                        if(dp[p][k][j]<dp[1-p][l][k]+temp)
                            dp[p][k][j]=dp[1-p][l][k]+temp;
                    }
                }
            }
        }
    }
    for(i=0; i<num&&st[i]<max; i++)
        for(j=0; j<num&&st[j]<max; j++)
        {
            temp=dp[p][i][j];
            if(temp>res)
                res=temp;
        }
    printf("%d\n",res);
}

int main()
{
    int i,j,temp;
    num=0;
    memset(b,0,sizeof(b));
    chushihua();
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(a,0,sizeof(a));
        for(i=1; i<=n; i++)
        {
            a[i]=0;
            for(j=1; j<=m; j++)
            {
                scanf("%d",&temp);
                a[i]=(a[i]<<1)+temp;
            }
        }
        solve();
    }
    return 0;
}

 

posted on 2013-11-29 19:58  后端bug开发工程师  阅读(288)  评论(0编辑  收藏  举报

导航