状态压缩--方格取数
来源:互联网 发布:java nio和io的区别 编辑:程序博客网 时间:2024/05/20 07:14
标签: ACM
题目:
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
output
对于每个测试实例,输出可能取得的最大的和
sample input
3
75 15 21
75 15 28
34 70 5
sample output
188
解题思路:
- 找出每一行的状态的状态用二进制保存,0表示该位置不取,1表示取
- 将每一行所有状态的和保存到数组里面
- 从第二行开始找该行与上一行不冲突的所有状态,保存状态最大之和, 一直找到最后一行为止
- 遍历最后一行所有状态数值之和,最大值即为答案
需要用到异或,感觉在状态压缩里面特别重要
(1)按位与运算符(&)
按位与运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 & 0 = 0, 0 & 1 = 0, 1 & 0 = 0, 1 & 1 = 1。
即同为 1 的位,结果为 1,否则结果为 0。
例如,设3的内部表示为011
5的内部表示为101
则3&5
的结果为001
(2)按位或运算符(|)
按位或运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 | 0 = 0, 0 | 1 = 1, 1 | 0 = 1, 1 | 1 = 1
即只要有1个是1的位,结果为1,否则为0。
(3)按位异或运算符(^)
按位异或运算将两个运算分量的对应位按位遵照以下规则进行计算:
0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0
即相应位的值相同的,结果为 0,不相同的结果为 1。
例如,013^035
结果为026
。
异或运算的意思是求两个运算分量相应位值是否相异,相异的为1,相同的为0。按位异或运算的典型用法是求一个位串信息的某几位信息的反。如欲求整型变量j的最右4位信息的反,用逻辑异或运算017^j,就能求得j最右4位的信息的反,即原来为1的位,结果是0,原来为0的位,结果是1。
AC代码
#include <iostream>#include <string.h>#define M 17720 //每一行有最大17711种状态#define N 21using namespace std;int map[N][N]; //储存输入的数字int sum[N][M]; //第i行第j种状态的总和int state[M];int dp[N][M];int n,p;int max(int a,int b) // 求最大值{ return (a>b?a:b);}bool checkLine(int i) //检查该状态是否符合题意{ return !(i&(i>>1));}bool checkTwoLine(int i,int j) //检查该行与上一行是否符合题意{ return !(i&j);}void init(){ int i,j,k; p=0; memset(sum,0,sizeof(sum)); for(i=0;i<(1<<n);i++) //将n改为20测试获得每一行有17711种状态 if(checkLine(i)) state[p++]=i; for(i=0;i<n;i++) for(j=0;j<p;j++) for(k=0;k<n;k++) if((state[j]>>k)&1) sum[i][j]+=map[i][n-k-1];}void solve(){ int i,j,k; memset(dp,0,sizeof(dp)); for(i=0;i<p;i++) dp[0][i]=sum[0][i]; for(i=1;i<n;i++) //遍历每一行 for(j=0;j<p;j++) //遍历该行的每一种状态 for(k=0;k<p;k++) //遍历上一行的每一种状态 { if(checkTwoLine(state[j],state[k])) dp[i][j]=max(dp[i][j],sum[i][j]+dp[i-1][k]); } int ans=dp[n-1][0]; for(i=1;i<p;i++) { if(ans<dp[n-1][i]) ans=dp[n-1][i]; } cout<<ans<<endl;}int main(){ while (cin>>n) { int i,j; memset(map,0,sizeof(map)); for(i=0;i<n;i++) for(j=0;j<n;j++) cin>>map[i][j]; init(); solve(); } return 0;}
阅读全文
0 0
- 状态压缩--方格取数
- hdu1565 方格取数(状态压缩)
- hdu2167 方格取数 状态压缩dp
- hdu1565方格取数(1)【状态压缩】
- 方格取数之状态压缩
- hdu 1565 方格取数(1)(DP 状态压缩)
- hdu 1565 方格取数(1)(状态压缩DP)
- hdu 1565 方格取数(1)(状态压缩dp)
- HDU1565 方格取数(1) (状态压缩DP)
- HDU-1565 方格取数(1) 状态压缩DP
- hdu-1565(方格取数(1))---状态压缩
- HDU1565:方格取数(1) (状态压缩DP)
- HDU 1565 方格取数(1)(状态压缩DP)
- hdu 1565 方格取数(1) (状态压缩dp)
- hdu 1565 方格取数(1) 状态压缩+dp
- HDU 1565 方格取数(1) (状态压缩)
- HDU 1565 方格取数(1) 状态压缩DP
- HDU1565方格取数(1)(状态压缩DP)
- 算法 渐进 大θ定理 / 实例分析
- asp.net web api
- 13. Roman to Integer(12/6/2017)
- 2017 SCNU软件学院 蓝桥杯预选赛 题解(非官方)
- 欢迎使用CSDN-markdown编辑器
- 状态压缩--方格取数
- 【状态压缩】---状态压缩dp第一题
- [状态压缩]---Brackets
- [状态压缩]---区间dp第一题
- python一周速成学习笔记
- python实战--数据结构二叉树
- 【线段树】-敌兵布阵 --单节点更新
- [全排列]--A Number Puzzle
- Maven项目下载sqljdbc4-4.0.jar失败