典型的状态压缩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[][], dp[][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 = ; i <= n; i++)
for (j = ; j <= n; j++)
scanf("%d", &a[i][j]);
memset(dp[], , sizeof(dp[]));
maxSum = ;
for (i = ; i <= n; i++)
for (j = ; j < m; j++){
lmax = ;
for (k = ; k < m; k++){
if (!(stu[j] & stu[k]) && lmax < dp[i - ][k]) //如果上下相容,且当前的值大于原来最大值
lmax = dp[i - ][k];
}
dp[i][j] = lmax + stuValue(i, j); //计算状态dp[i][j]
if (maxSum < dp[i][j])
maxSum = dp[i][j];
}
printf("%d\n", maxSum);
}
return ;
}
int initialization(int n){
int ant = ;
for (int i = ; i < ( << n); i++){
if (!(i&(i << )))
stu[ant++] = i;
}
return ant;
}
int stuValue(int i, int j){ //第i行,状态为stu[j]时候第i行的值
int k = stu[j], t = , sum = ;
while (k>){
if (k & )
sum += a[i][t];
t++;
k = k >> ;
}
return sum;
}

HDU1565方格取数的更多相关文章

  1. HDU1565 方格取数(1) —— 状压DP or 插头DP(轮廓线更新) or 二分图点带权最大独立集(最小割最大流)

    题目链接:https://vjudge.net/problem/HDU-1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory L ...

  2. HDU-1565 方格取数(1)

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Me ...

  3. HDU1565 方格取数 &&uva 11270 轮廓线DP

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  4. Hdu-1565 方格取数(1) (状态压缩dp入门题

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  5. HDU1565 方格取数(1)

    Problem Description 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数 ...

  6. HDU1565 方格取数1(构图+网络流最大独立集合)

    题目大意:给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. 解题思路:最大点 ...

  7. HDU1565 方格取数(1)(状态压缩dp)

    题目链接. 分析: 说这题是状态压缩dp,其实不是,怎么说呢,题目数据太水了,所以就过了.手动输入n=20的情况,超时.正解是网络流,不太会. A这题时有个细节错了,是dp[i][j]还是dp[i][ ...

  8. HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]

    题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...

  9. HDU 1565&1569 方格取数系列(状压DP或者最大流)

    方格取数(2) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

随机推荐

  1. 04 JVM是如何执行方法调用的(下)

    虚方法调用 Java 里所有非私有实例方法调用都会被编译成 invokevirtual 指令,而接口方法调用会被编译成 invokeinterface 指令.这两种指令,均属于 Java 虚拟机中的虚 ...

  2. Leetcode 632.最小区间

    最小区间 你有 k 个升序排列的整数数组.找到一个最小区间,使得 k 个列表中的每个列表至少有一个数包含在其中. 我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < ...

  3. 深入学习之mysql(四)聚合函数

    聚合函数:COUNT统计记录的条数.SUM求和函数.AVG求平均值.MAX求最大值.MIN求最小值   一.COUNT练习: 1.统计学校一共有多少个学生: mysql> SELECT COUN ...

  4. docker exec小脚本

    经常要使用docker exec -it containerID bash 进入docker内部进行一些操作,干脆把它写成shell脚本节省时间. # 查看需要操作的容器id $ docker ps ...

  5. MpLab设置编译文件输出路径

    MpLab设置编译文件输出路径

  6. ZigBee学习五 无线温度检测

    ZigBee学习五 无线温度检测 1)修改公用头文件GenericApp.h typedef union h{ uint8 TEMP[4]; struct RFRXBUF { unsigned cha ...

  7. BZOJ 3674 可持久化并查集加强版(主席树变形)

    3673: 可持久化并查集 by zky Time Limit: 5 Sec  Memory Limit: 128 MB Submit: 2515  Solved: 1107 [Submit][Sta ...

  8. [luoguP3332] [ZJOI2013]K大数查询(树套树)

    传送门 一开始想的是区间线段树套权值线段树,结果好像不能实现. 然后题解是权值线段树套区间线段树. 区间线段树上标记永久化就省去了pushdown的操作减少常数. 标记永久化的话..yy不出来就看代码 ...

  9. 蔬菜(vegetable)

    蔬菜(vegetable) 题目描述 题目背景:您使用脚本刷出了上题游戏 998244353 关的最高分 (最优解),心满意足的准备点继续学习,忽然一条弹窗弹了出来:你想明白活着的意义吗?你想真正的. ...

  10. Python基础教程笔记 第一章

    /  表示整除,当导入_future_模块中的version时,/ 表示正常的的除法, 此时可用//表示整除,不论数字是整型还是浮点型,都可以用//表示整除. ** 表示幂次方  例如 2**3    ...