hdu 2167 状态压缩dp

/*
状态转移方程:dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]);
*/
#include<stdio.h>
#include<string.h>
#define N   16
int ma[N][N];
int num[N];
char s[150];
int lower[15];//储存二级制
int dp[N][1<<N];//储存最优状态
int now[1<<N],cu;//储存合法的状态
int sum[N][1<<N];//储存第i行第j个状态的总的权值和
int Max(int a,int b)
{
    return a>b?a:b;
}
int main()
{
    int n,i,j,k,maxx;
    lower[0]=1;
    for(i=1; i<=15; i++)
        lower[i]=lower[i-1]*2;
    while(gets(s))
    {
        k=0;
        j=0;
        n=0;
        for(i=0; s[i]; i++)
        {
            if(j&&s[i]==' ')
            {
                ma[1][++n]=k;
                j=0;
                k=0;
            }
            if(s[i]>='0'&&s[i]<='9')
            {
                k=k*10+s[i]-'0';
                j=1;
            }
        }
        if(j)
            ma[1][++n]=k;
        for(i=2; i<=n; i++)
            for(j=1; j<=n; j++)
                scanf("%d",&ma[i][j]);
        cu=0;
        for(i=0; i<(1<<n); i++)//储存合法的状态
        {
            if(i<<1&i)continue;
            now[++cu]=i;
        }
        memset(sum,0,sizeof(sum));
        memset(dp,0,sizeof(dp));
        for(i=1; i<=n; i++)
            for(j=1; j<=cu; j++)
                for(k=0; k<n; k++)//因为在二进制中1代表的就是lower[0],如果k从1开始的话,lower[1]=2,就缺少了1的情况
                    if(lower[k]&now[j])sum[i][j]+=ma[i][k+1];//lower[k]才是有效地
        for(i=1; i<=cu; i++)//初始化第一行
            dp[1][i]=sum[1][i];
        for(i=2; i<=n; i++)
            for(j=1; j<=cu; j++)
                for(k=1; k<=cu; k++)
                {
                    if(now[j]&now[k])continue;
                    if(now[j]&(now[k]<<1))continue;//如果和对角线和上面都没有相邻就符合
                    if(now[j]&(now[k]>>1))continue;
                    dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]);
                }
        maxx=-1;
        for(i=1; i<=cu; i++)//求出所有状态的最大值
            if(maxx<dp[n][i])
                maxx=dp[n][i];
        printf("%d
",maxx);
        gets(s);
        gets(s);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410620.html