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[20000];//存状态
int mp[25][25];
int d[25][20000];//d[i][j]表示第i行第j种状态时的最大和(这时的最大和是1~i行所能取得的最大和)
int n;
///将符合要求的状态保存下来,即没有两个一相邻的情况
int init(int n)
{int M=0;for(int i=0 ; i<n ; i++)if((i&(i>>1))==0)///不相邻status[M++] = i;return M;
}
///计算该状态的和
int cal(int x,int t)
{int sum=0,j=n-1;while(t){if(t&1)///最后为是1sum+=mp[x][j];j--;t >>= 1;}return sum;
}
int main( )
{while(scanf("%d",&n)!=EOF){if(n == 0)//加上这句用C++提交能过,没这句C++就过不了,但G++能,不知道为啥
        {printf("0\n");continue;}int M = init(1<<n);///初始化,找到状态一有多少memset(d,0,sizeof(d));for(int i=0 ; i<n ; i++)for(int j=0 ; j<n ; j++)scanf("%d",&mp[i][j]);for(int i=0 ; i<M ; i++)d[0][i]=cal(0,status[i]);for(int i=1 ; i<n ; i++)///第i行
        {for(int j=0 ; j<M ; j++)///枚举第i行状态
            {int t=cal(i,status[j]);for(int k=0 ; k<M ; k++)///枚举上一行的状态,即第i-1行
                {if(status[j]&status[k])///上一行和这一行存在上下相邻的1 continue;d[i][j]=max(d[i-1][k]+t,d[i][j]);}}}int ans=0;for(int i=n-1 , j=0 ; j<M ; j++)ans=max(d[i][j],ans);printf("%d\n",ans);}return 0;
}

View Code

转载于:https://www.cnblogs.com/shuaihui520/p/9132788.html

HDU 1565 方格取数(简单状态压缩DP)相关推荐

  1. 网络流(最大流) HDU 1565 方格取数(1) HDU 1569 方格取数(2)

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

  2. hdu 1565 方格取数(1)(状态压缩dp)

    方格取数(1)                                                                 Time Limit: 10000/5000 MS (J ...

  3. hdu 1565 方格取数(1)

    我用状态压缩做的. 一个有少于18000的合格状态,再DP 就好. #include<cstdio> #include<iostream> #include<cstrin ...

  4. HDU 1565 方格取数(1) ——插头DP

    [题目分析] 其实直接状压就可以了. 但是有点闲,又写了一个可读性极差,智商低下,很(gou)好(pi)的代码 [代码] #include <cstdio> #include <cs ...

  5. hdu 1569 方格取数(2) 最大点权独立集

    二分图. 最大点权独立集=总权-最小点权覆盖集. 哪位大神能给一些二分图 最大点权独立集等等 的相关资料!!!!!跪谢 用网络流求解最小点权覆盖集即可,建图不讲了. #include<cstdi ...

  6. [蓝桥杯][算法训练VIP]方格取数(双线程dp)

    题目描述 设有N * N的方格图(N< =10),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字0. 某人从图的左上角的A 点(1,1)出发,可以向下行走,也可以向右走,直到到达右下 ...

  7. hdu 4640 Island and study-sister(状态压缩dp)

    先处理前两个学长到达各个点所需要的最少时间,在计算前两个学长和最后一个学长救出所有学妹的最少时间. #include<stdio.h> #include<string.h> # ...

  8. 状态压缩dp入门 第一题 POJ 3254 Corn Fields

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 6460   Accepted: 3436 Descr ...

  9. hdu2167 方格取数 状态压缩dp

    题意:      方格取数,八个方向的限制. 思路:      八个方向的不能用最大流了,四个的可以,八个的不能抽象成二分图,所以目测只能用dp来跑,dp[i][j]表示的是第i行j状态的最优,具体看 ...

最新文章

  1. 非抢占式优先算法例题_非抢占式高优先级调度算法
  2. python读文件代码-Python读取表格类型文件代码实例
  3. 使用Arduino模块实施无线信号的重放攻击
  4. 重磅!阿里开源自研语音识别模型DFSMN,准确率高达96.04%
  5. nginx http子模块conf的初始化
  6. json非法字符有哪些_JSON文件中非法字符的处理
  7. 有什么是你追了很多女生都失败后才知道的?
  8. idata界面_iData手持终端常见问题集,持续更新中...
  9. zookeeper在linux环境安装
  10. Mybatis_day1
  11. 【html、CSS、javascript-11】jquery-事件使用方法总结
  12. jquery ajax请求方式与提示用户正在处理请稍等,等待数据返回时loading的显示
  13. Arduino米思齐Mixly---人体声控灯
  14. 学嵌入式有必要参加培训吗
  15. 多张tif图片合成一张tif图片
  16. 搜狐新闻表情出现怪异现象
  17. 二进制反码求和java_有趣的二进制-浮点数
  18. 挖金矿问题java课程设计_动态规划--国王挖金矿问题
  19. CS231A:Vanishing Points and Lines
  20. 浅谈扫描二维码登录微信网页版与摇一摇传图的实现原理

热门文章

  1. 【python】快速对图像进行傅里叶变换
  2. 使用EfficientNet深度学习模型对植物叶病进行分类
  3. 【java】窗口和监听器的使用
  4. 1以下数字Oracle打印缺少0,Oracle SQL中缺少關鍵字
  5. java 1.7 环境变量_安装JDK1.8之后又安装1.7出现的环境变量问题
  6. python的调用函数_Python函数调用
  7. mysql数据库什么情况下会锁表_mysql数据库锁的产生原因及解决办法
  8. 网页版电脑桌面远程操控_我真的再也不买电暖器了 - 电暖器智能版
  9. 山西计算机应用基本技能,山西应用科技学院计算机应用技术专业课程介绍/专业代码-卧龙指南...
  10. 安卓10省电还是费电_拍照成罪魁祸首 安卓十大耗电App排行公布