• HDU1565方格取数


     典型的状态压缩DP问题。第i行的取法只受到第i-1行的影响。首先每一行的取法要相容(不能有两个相邻),然后相邻行之间也要相容。将每一个格子看做两种状态,1表示取,0表示不取。这样每一行就是一个01串,恰好可以看做是一个二进制数,那么该二进制数对应的十进制整数可以唯一的表示为当前第 i 行的状态。定义用dp[i][j]表示前 i 行状态为j 时最大和。其中状态 j对应的整数为stu[j],数组stu[]收录的是所有合法的状态,所谓合法状态是:若一个整数的二进制中没有任意两个1相邻,那么该整数就是合法的状态。判定方法:若 x&(x<<1)==0,则x是合法的状态。状态转移方程如下:

                        dp[i][j]=max{dp[i-1][w]}+value[i][j] (w&j==0) ;

    方程含义:j是第i行状态,w是第i-1行的状态,value[i][j]是第i行状态为j时第i行取法的和。从w状态转移到j状态需要满足w&j==0(他们是相容的)。计算时候需要枚举第i行所有状态w。代码如下:

    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    using namespace std;
    #define MAX_SIZE 17712                //当n=20时可以计算得到最多有11710中状态
    int stu[MAX_SIZE], Value[MAX_SIZE];    //stu表示总的状态数,MAX_SIZE表示对应状态的值
    int a[22][22], dp[22][MAX_SIZE];
    int initialization(int n);
    int stuValue(int i, int j);
    int main(){
        int i, j, k, m, n, lmax, maxSum;
        while (~scanf("%d", &n)){
            m = initialization(n);
            for (i = 1; i <= n; i++)
            for (j = 1; j <= n; j++)
                scanf("%d", &a[i][j]);
            memset(dp[0], 0, sizeof(dp[0]));  
            maxSum = 0;
            for (i = 1; i <= n; i++)
            for (j = 0; j < m; j++){
                lmax = 0;
                for (k = 0; k < m; k++){
                    if (!(stu[j] & stu[k]) && lmax < dp[i - 1][k])  //如果上下相容,且当前的值大于原来最大值
                        lmax = dp[i - 1][k];
                }
                dp[i][j] = lmax + stuValue(i, j);     //计算状态dp[i][j]
                if (maxSum < dp[i][j])
                    maxSum = dp[i][j];
            }
            printf("%d
    ", maxSum);
        }
        return 0;
    }
    int initialization(int n){
        int ant = 0;
        for (int i = 0; i < (1 << n); i++){
            if (!(i&(i << 1)))
                stu[ant++] = i;
        }
        return ant;
    }
    int stuValue(int i, int j){   //第i行,状态为stu[j]时候第i行的值
        int k = stu[j], t = 1, sum = 0;
        while (k>0){
            if (k & 1)
                sum += a[i][t];
            t++;
            k = k >> 1;
        }
        return sum;
    }
  • 相关阅读:
    docker相关
    多线程
    设计模式
    ftp下载乱码问题
    Windows无法启动SQL server 代理服务(服务器)错误1067:进程意外终止
    Struts2 if标签
    Java项目编译时经常会出现不编译,或者报一些假性错误
    ajaxSubmit 上传文件 提示下载json处理
    MySQL中优化sql语句查询常用的30种方法
    mybatis 中的where标签
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5443864.html
Copyright © 2020-2023  润新知