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 包括多 ...
随机推荐
- Android键盘属性
在主xml中android:windowSoftInputMode的属性"stateUnspecified"软键盘的状态(是否它是隐藏或可见)没有被指定.系统将选择一个合适的状态或 ...
- java 矩阵转置算法
工作中用到了行列转置,把这两种情况的算法记下来,以便后用 1.行列数相等的转置 /** * @description 矩阵转置 * @author oldmonk * @time 2017年8月18日 ...
- 框架之 hibernate之各种查询
1. Hibernate的查询方式 2. Hibernate的查询策略 案例:使用Hibernate完成查询所有联系人功能 需求分析 1. 完成所有的联系人的查询 技术分析之Hibernate框架的查 ...
- Eclipse安装Web/JavaEE插件、Eclipse编写HTML代码
1 Eclipse没有Web插件和JavaEE插件咋整 1.1 在Eclipse中菜单help选项中选择install new software选项 1.2 在work with 栏中输入 http: ...
- ruby 类方法、实例方法、类变量
###################### #类变量 ###################### class Cloud @@count=0 def initialize(user,passwor ...
- 业务逻辑: Quartz的整合应用
1. 请谈一下你对Quartz的理解 思路:根据他解决的什么问题方面去阐述 2. 完成quartz和spring的整合应用 思路:触发时间.任务调度工程 步骤: 1. 创建maven工程,并导入qua ...
- ROS Learning-029 (提高篇-007 A Mobile Base-05) 控制移动平台 --- (Python编程)控制虚拟机器人的移动(精确的制定目标位置)
ROS 提高篇 之 A Mobile Base-05 - 控制移动平台 - (Python编程)控制虚拟机器人的移动(精确的制定目标位置) 使用 odometry 消息类型 重写 out_and_ba ...
- c# 新中新二代身份证阅读,包含头像,支持华视
需要用到dll和文件: 其中3个dll文件是需要调用的dll,license.dat文件为解压图片的授权文件 以下是需要用到的dll里面的方法: /************************端口 ...
- 自己封装一个MySignal函数,方便以后直接copy.
传统的signal可能会有信号未决或者信号重入或多或少的问题,毕竟这个函数已经很多年了. 所以推荐使用sigaction函数,但是sigaction函数相对signal较为复杂,而且每次要写一大堆.因 ...
- WPF开源界面库
WPF开源项目 WPF有很多优秀的开源项目,我以为大家都知道,结果,问了很多人,其实他们不知道.唉,太可惜了! 先介绍两个比较牛逼的界面库 1.MaterialDesignInXamlToolkit ...