码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 2167 状压DP

时间:2015-07-25 18:32:51      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

方格取数问题,给出n*n矩阵,3<n<15

求能取得的最大和,要求取某个位置的数以后,其周围的8个数字均不能再取

先预处理出来所有的可取状态,n=15时只有1597个状态,然后地推求解即可


#include "stdio.h"
#include "string.h"
int n,ans;
int b[21],a[21][21],s[1700];
int dp[21][70001],sum[21][70001];

int Max(int a,int b)
{
    if (a<b) return b;
    else return a;
}
void DP()
{
    int tot,cnt,i,j,k;
    tot=b[n]-1;
    cnt=0;
    memset(dp,0,sizeof(dp));
    memset(sum,0,sizeof(sum));

    for (i=0;i<=tot;i++)
    {
        if ((i<<1)&i) continue;
        s[cnt++]=i;
    }
    for (i=0;i<n;i++)
        for (j=0;j<cnt;j++)
            for (k=0;k<n;k++)
            if (b[k]&s[j])
                sum[i][j]+=a[i][k];

    for (i=0;i<cnt;i++)
        dp[0][i]=sum[0][i];

    for (i=1;i<n;i++)
        for (j=0;j<cnt;j++)
            for (k=0;k<cnt;k++)
            {
                if (s[j]&s[k]) continue;
                if ((s[j]<<1)&s[k]) continue;
                if ((s[j]>>1)&s[k]) continue;
                dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]);
            }

    ans=0;
    for (i=0;i<cnt;i++)
        ans=Max(ans,dp[n-1][i]);

}

int main()
{
    int i,k,j;
    char str[101];
    b[0]=1;
    for (i=1;i<=20;i++)
        b[i]=b[i-1]*2;


    while (gets(str))
    {
        n=(strlen(str)+2)/3;
        k=0;
        for (i=0;i<str[i];i+=3)
            a[0][k++]=(str[i]-'0')*10+str[i+1]-'0';

        for (i=1;i<n;i++)
            for (j=0;j<n;j++)
            scanf("%d",&a[i][j]);

        DP();
        printf("%d\n",ans);
        getchar();getchar();

    }
    return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

HDU 2167 状压DP

标签:

原文地址:http://blog.csdn.net/u011932355/article/details/47057773

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!