方格取数(1)(HDU-1565)
Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
Output
对于每个测试实例,输出可能取得的最大的和
Sample Input
3
75 15 21
75 15 28
34 70 5Sample Output
188
思路:状压DP
题目中 n<=20,但仅需枚举每一行中满足条件的状态,当实际上当 n=20 时,合法状态为 16,因此实际上 n<=16
用 dp[i][j] 表示前 i 行的第 i 行取 j 种状态时的最大和,用 sum[i][j] 表示第 i 行取第 j 个状态的取值总和,则有 dp[i][j] = max(dp[i][j], dp[i-1][k] + sum[i][j]) ,当两行状态相与为 0 即可进行状态转移
Source Program
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstdlib>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<ctime>
#include<vector>
#define INF 0x3f3f3f3f
#define PI acos(-1.0)
#define N 16
#define MOD 10007
#define E 1e-6
#define LL long long
using namespace std;
int n;
int a[21][21];
int dp[21][1<<N],sum[21][1<<N];
int sta[1<<N];
int calculate(int k,int state){//求第i行状态为state时的取值总和int res=0;for(int i=0;i<n;i++)if((state>>i)&1)res+=a[k][n-1-i];return res;
}
int main()
{while(scanf("%d",&n)!=EOF){for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%d",&a[i][j]);memset(sum,0,sizeof(sum));memset(dp,0,sizeof(dp));/*数据处理,求出所有取值和*/int len=0;for(int i=0;i<(1<<n);i++)//枚举所有状态if(!(i&(i>>1)))//判断本行状态sta[len++]=i;for(int i=0;i<n;i++)//求第i行取第j个状态的取值总和for(int j=0;j<len;j++)sum[i][j]+=calculate(i,sta[j]);/*状态转移,求最大和*/for(int i=0;i<len;i++)dp[0][i]=sum[0][i];for(int i=1;i<n;i++)//行数for(int j=0;j<len;j++)//本行状态for(int k=0;k<len;k++)//上一行状态if(!(sta[j]&sta[k]))dp[i][j]=max(dp[i][j],dp[i-1][k]+sum[i][j]);/*寻找最大和*/int res=dp[n-1][0];for(int i=1;i<len;i++)if(res<dp[n-1][i])res=dp[n-1][i];printf("%d\n",res);}return 0;
}
方格取数(1)(HDU-1565)相关推荐
- 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和 ...
- hdu 1565 方格取数(1)(状态压缩dp)
方格取数(1) Time Limit: 10000/5000 MS (J ...
- hdu 3657 最大点权独立集变形(方格取数的变形最小割,对于最小割建图很好的题)...
转载:http://blog.csdn.net/cold__v__moon/article/details/7924269 /* 这道题和方格取数2相似,是在方格取数2的基础上的变形.方格取数2解法: ...
- 最小割 ---- 二分图最大独立集(集合冲突模型) ---- 骑士共存 方格取数(网络流24题)
二分图独立集 定理: 二分图最大独立集=n - 二分图最大匹配 其实二分图独立集是特殊的一种最大权闭合子图.我们根据上文"收益"的思想,把选某个点的收益看为1,左部节点为正权点,右 ...
- 【网络流24题】I、 方格取数问题(二分图的最大独立集/最小割)
I. 方格取数问题(二分图的最大独立集/最小割) [问题分析] 二分图点权最大独立集,转化为最小割模型,从而用最大流解决. [建模方法] 首先把棋盘黑白染色,使相邻格子颜色不同,所有黑色格子看做二分图 ...
- P2774 方格取数问题 网络最大流 割
P2774 方格取数问题:https://www.luogu.org/problemnew/show/P2774 题意: 给定一个矩阵,取出不相邻的数字,使得数字的和最大. 思路: 可以把方格分成两个 ...
- hdu2167 方格取数 状态压缩dp
题意: 方格取数,八个方向的限制. 思路: 八个方向的不能用最大流了,四个的可以,八个的不能抽象成二分图,所以目测只能用dp来跑,dp[i][j]表示的是第i行j状态的最优,具体看 ...
- [codevs 1907] 方格取数3
[codevs 1907] 方格取数3 题解: 二分图染色.最大点权独立集. 因为要用到最大独立集的一些思路,故先写了一篇最大独立集的题解:http://blog.csdn.net/qq_211102 ...
- [codevs 1227] 方格取数2
[codevs 1227] 方格取数 2 题解: 注:这是CODEVS的方格取数2,走k次的版本. 因为每个格子可以走无数次,但走过一次之后数字就变成了0,也就是只有一次可以加上格子里的数字.所以要拆 ...
- HDU-1569 方格取数(2) 最小割最大流
题义很简单,还记得方格取数(1)的时候,使用状态压缩写的,这里由于行列数太大,因此无法进行压缩.所以要运用的最小割最大流的思想来解这道题. 大概是这样分析的,题义是要我们求在一个方格内取出N个点,使得 ...
最新文章
- 浅析操作系统和Netty中的零拷贝机制
- 远程手机测试机房的建立
- 发布一个实体类属性生成小工具,给开发加点料
- [转] 《完美程式设计指南》Effective Delphi
- 查看Oracle数据库表空间大小(空闲、已使用),是否要增加表空间的数据文件
- python代码直接关机_python实现电脑自动关机
- MYSQL SELECT 过程 转
- 【李宏毅2020 ML/DL】P115-117 Actor-Critic Sparse Reward Imitation Learning
- 使用PowerDesigner进行面向对象分析与UML建模(转)
- [LeetCode] 860. 柠檬水找零 lemonade-change(贪心算法)
- 一文带你详细了解机房搬迁工作步骤及方案,强烈建议收藏备用!
- tkmybatis 权威指南 官方文档
- 太牛了!阿里p8全面透彻剖析《Netty权威指南》,程序员必看!
- JAVA设计模式征服之路-00-设计模式简介
- 如何领取门票参加中国北京科技产业博览会?
- pg之使用pg_upgrade进行大版本升级
- maven clean、install命令
- 亚马逊运营经常忽略的买家秀,主图开箱视频的重要性
- 解决提示“npm audit fix“问题
- 【来袭】iTOP-3568开发板Android11系统移植视频教程