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)的更多相关文章

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

    方格取数(1) Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  2. HDU 1565 - 方格取数(1) - [状压DP][网络流 - 最大点权独立集和最小点权覆盖集]

    题目链接:https://cn.vjudge.net/problem/HDU-1565 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32 ...

  3. HDU1565 方格取数(1)(状态压缩dp)

    题目链接. 分析: 说这题是状态压缩dp,其实不是,怎么说呢,题目数据太水了,所以就过了.手动输入n=20的情况,超时.正解是网络流,不太会. A这题时有个细节错了,是dp[i][j]还是dp[i][ ...

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

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

  5. HDU 1565 方格取数(1) 轮廓线dp

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1565 方格取数(1) Time Limit: 10000/5000 MS (Java/Others) ...

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

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

  7. hdu 2167 方格取数 【状压dp】(经典)

    <题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的  3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数 ...

  8. HDU 1565 方格取数(1)(最大点权独立集)

    http://acm.hdu.edu.cn/showproblem.php?pid=1565 题意: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格 ...

  9. HDU 1565 方格取数 状压dp

    题目: 给你一个n*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大. Input 包括多 ...

随机推荐

  1. hadoop再次集群搭建(2)-配置免秘钥ssh登录

    SSH对于大多程序员都不陌生,目前主流的云服务提供上也是通过SSH来提供链接的安全保障,比如AWS通过使用下载的私钥(private key)实现与EC2实例安全连接.GitHub通过上传的公钥(pu ...

  2. MSER

    1.注释很全的分析:http://blog.csdn.net/zhaocj/article/details/40742191 2.opencv采用的mser实现方法 * 1. the gray ima ...

  3. 内核文件ntoskrnl.exe,ntkrnlpa.exe的区别??

    除了标题中说到的两个exe文件之外,还有另外两个ntkrnlmp.exe和ntkrpamp.exe.因为我目前用到的只是标题中的两个. 其中,我在网上搜索到的关于SSDT HOOK 的资料,举的例子, ...

  4. 【IMOOC学习笔记】多种多样的App主界面Tab实现方法(四)

    ViewPagerIndicator+ViewPager 要想使用ViewPagerIndicator,要使用到viewPagerlibrary开源库 top.xml <?xml version ...

  5. ecto使用

  6. Django之后台管理一

    所有的网站都有一个管理后台来对所有的网站数据进行管理.那么Django的后台管理是如何进行的.在网页中输入http://127.0.0.1:8001/admin.得到如下的登录界面 在这里可以看到管理 ...

  7. Harbor安装 -- 企业级Registry仓库

    (一)Harbor安装 -- 企业级Registry仓库 以下文章转自http://www.jianshu.com/p/2ebadd9a323d 根据Harbor官方描述: Harbor是一个用于存储 ...

  8. AI-Info-Micron-Insight:工业 5.0,伟大的思想将殊途同归

    ylbtech-AI-Info-Micron-Insight:工业 5.0,伟大的思想将殊途同归 1.返回顶部 1. 工业 5.0,伟大的思想将殊途同归 两个头脑比一个好吗?似乎如此,尤其是当其中一个 ...

  9. pychram编写代码鼠标变粗处理

    现象:如下图 解决: 键盘 点击 insert 按钮即可解决

  10. [SinGuLaRiTy] 2017-07-26 综合性测试

    [SinGuLaRiTy-1032] Copyright (c) SinGuLaRiTy 2017. All Rights Reserved.               单词 (word) 题目描述 ...