HDU 1565 方格取数(简单状态压缩DP)
http://acm.hdu.edu.cn/showproblem.php?pid=1565
对于每一个数,取或者不取,用0表示不取,1表示取,那么对于每一行的状态,就可以用一个二进制的数来表示。比如5的二进制为101,就表示取第一个数,不取第二个数,取第三个数。
将符合要求的状态保存下来,什么是符合要求的呢?即二进制数中不存在相邻的1(110,011都是不符合要求的)。可以用移位并按位与的办法来判断,举个例子:110左移一位为011 ,110&011 = 1,不符合要求;101左移一位为010,101&010=0,符合要求,这是判断同一行时的方法。
判断上下两行,只需将上下两行的状态按位与即可。(PS:在纸上写写,和容易就能看出来)
然后枚举每一行的状态和上一行的状态,找出不与上一个状态冲突的情况,然后计算,选择当前状态的最大值
AC
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
int status[];//存状态
int mp[][];
int d[][];//d[i][j]表示第i行第j种状态时的最大和(这时的最大和是1~i行所能取得的最大和)
int n;
///将符合要求的状态保存下来,即没有两个一相邻的情况
int init(int n)
{
int M=;
for(int i= ; i<n ; i++)
if((i&(i>>))==)///不相邻
status[M++] = i;
return M;
}
///计算该状态的和
int cal(int x,int t)
{
int sum=,j=n-;
while(t)
{
if(t&)///最后为是1
sum+=mp[x][j];
j--;
t >>= ;
}
return sum;
}
int main( )
{ while(scanf("%d",&n)!=EOF)
{
if(n == )//加上这句用C++提交能过,没这句C++就过不了,但G++能,不知道为啥
{
printf("0\n");
continue;
}
int M = init(<<n);///初始化,找到状态一有多少
memset(d,,sizeof(d));
for(int i= ; i<n ; i++)
for(int j= ; j<n ; j++)
scanf("%d",&mp[i][j]);
for(int i= ; i<M ; i++)
d[][i]=cal(,status[i]);
for(int i= ; i<n ; i++)///第i行
{
for(int j= ; j<M ; j++)///枚举第i行状态
{
int t=cal(i,status[j]);
for(int k= ; k<M ; k++)///枚举上一行的状态,即第i-1行
{
if(status[j]&status[k])///上一行和这一行存在上下相邻的1
continue;
d[i][j]=max(d[i-][k]+t,d[i][j]);
}
}
}
int ans=;
for(int i=n- , j= ; j<M ; j++)
ans=max(d[i][j],ans);
printf("%d\n",ans); }
return ;
}
HDU 1565 方格取数(简单状态压缩DP)的更多相关文章
- hdu 1565 方格取数(1) 状态压缩dp
方格取数(1) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]
题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...
- HDU1565 方格取数(1)(状态压缩dp)
题目链接. 分析: 说这题是状态压缩dp,其实不是,怎么说呢,题目数据太水了,所以就过了.手动输入n=20的情况,超时.正解是网络流,不太会. A这题时有个细节错了,是dp[i][j]还是dp[i][ ...
- 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)
HDU 1565 方格取数(1) 给你一个n*n的格子的棋盘,每个格子里面有一个非负数.从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的 ...
- HDU 1565 方格取数(1) 轮廓线dp
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) ...
- hdu 1565 方格取数(1)(状态压缩dp)
方格取数(1) Time Limit: 10000/5000 MS (J ...
- hdu 2167 方格取数 【状压dp】(经典)
<题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的 3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数 ...
- HDU 1565 方格取数(1)(最大点权独立集)
http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格 ...
- HDU 1565 方格取数 状压dp
题目: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. Input 包括多 ...
随机推荐
- os.path.join合并 os.path.dirname返回上一级目录 os.path.exists(path) os.stat('path/filename')获取文件/目录信息
import os str1 = "grsdgfd" str2 = "wddf" str3 = "gddgs" # print(str1 + ...
- vray学习笔记(5)-学习资料
首先肯定是vray的官方的资料了: 一个是教程 https://docs.chaosgroup.com/display/VRAY3MAX/Tutorials 一个是帮助文件 https://docs. ...
- Luogu 3193 [HNOI2008]GT考试
BZOJ1009 妙! 推荐这篇题解: https://www.luogu.org/blog/Edgration/solution-p3193 考虑设计dp,设$f_{i, j}$表示长串匹配到i,短 ...
- vue 之 Nodejs介绍
Nodejs英文网:https://nodejs.org/en/ 中文网:http://nodejs.cn/ 我们会发现这样一句话: 翻译成中文如下: Node.js 是一个基于 Chrome V8 ...
- thrift使用小记
Thrift是一个跨语言的服务部署框架,最初由Facebook于2007年开发,2008年进入Apache开源项目.Thrift通过一个中间语言(IDL, 接口定义语言)来定义RPC的接口和数 ...
- Java 在本地开发环境部署多个 spring 项目
修改Tomcat 的 server.xml 文件 路径:C:\JAVA\apache_tomcat_8.5.11\conf\server.xml : 每个web项目的端口号不同,且存储的目录相同但是文 ...
- Vue v-if ToolList
可根据v-if="IsOk",动态判断标签是否展示 <template> <div id="app"> <input type=& ...
- MySQL Index Condition Pushdown 原理与解析
Index Condition Pushdown(ICP)是针对mysql使用索引从表中检索行数据时的一种优化方法. 原理: 在没有ICP特性之前,存储引擎根据索引去基表查找并将数据返回给mysq ...
- echarts设置地图大小比例,大小设置
设置地图大小可通过以下属性设置: geo.aspectScale number [ default: 0.75 ] 这个参数用于 scale 地图的长宽比. 最终的 aspect 的计算方式是:geo ...
- The Datawarehouse's future is bright
The Future Data Warehouse Professionals I hava remarked many times that a successful data warehouse ...