zoukankan      html  css  js  c++  java
  • 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;
    }
    

  • 相关阅读:
    计时器C#
    MySQL Database Command Line Client
    C#小爬虫,通过URL进行模拟发送接收数据
    C#导入导出Excele数据
    正则表达式动态分隔符
    C#中的枚举
    C#中的ToString格式大全
    C# 序列化与反序列化
    C# 对xml进行操作
    时间标签DateTime
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410620.html
Copyright © 2011-2022 走看看