Hdu 4539 【状态DP】.cpp
题意:
一个炮兵可以攻打和他之间曼哈顿距离为2的士兵,给出你一块n*m的战场,告诉你哪些地方可以站人哪些地方不可以,问你最多可以安放多少个士兵?
n <= 100, m <= 10
思路:
这道题暴力是不可以的,因为状态太多了
可以状态DP来做,用一个数组G记录战场的限制,然后用一个数组dp[当前状态或者是前一个状态][当前状态的十进制表示][前一个状态的十进制表示]
因为用的是G[1<<m]来表示,所以时间复杂度是n*(2^m)*(2^m)*(2^m),m最多为10,所以时间复杂度就是10*1024*1024*1024,显然这样的时间复杂度也是说不过去的。所以就用一个预处理,预处理出满足基本条件的状态,即水平距离上曼哈顿距离不为2的状态,我用bir[][2]来存预处理出来的基本状态,bir[][0]表示的是预处理的符合基本条件状态的二进制数,bir[][1]表示的是这个状态中1的个数
Tips:
因为用的是滚动数组,所以应该注意n == 1的情况
位运算的优先级比 != 高,所以当我判断是否符合条件的时候应该直接写if(***)或者是if((***) != 0)
不能写 == 1,因为不管是哪种位运算,出来的结果都不一定是1,只能是 != 0
这里还有一个处理状态sta里面有多少个1的有效办法就是用lowbit(x) { return (x)&(-x)}, lowbit(x)可以提取x的最后一个1至最后一个0,这个可以利用补码原理来理解
这样不断 i -= lowbit(i), bir[][1]++, 就可以得到相对应1的个数了
Code:
#include <stdio.h>
#include <cstring>
#include <bitset>
#include <iostream>
#include <algorithm>
using namespace std; int n, m;
int G[], bir[<<|][], top;
int dp[][<<|][<<|];
int ans; int lowbit(int x)
{
return (x)&(-x);
} void init()
{
top = ;
int st = <<;
for (int i = ; i < st; ++i) {
if (((i>>)&i) || ((i<<)&i)) continue;
int tmp = i;
bir[top][] = i;
while (tmp) {
tmp -= lowbit(tmp);
bir[top][]++;
}
top++;
}
} void DP()
{
int st = <<m;
for (int i = ; i < top && bir[i][] < st; ++i)
if ((bir[i][]&(G[]^(st-))) != ) continue; /// == 1!!!!!
else ans = max(ans, bir[i][]); if (n == ) return; for (int i = ; i < top && bir[i][] < st; ++i) {
for (int j = ; j < top && bir[j][] < st; ++j) {
if ( (bir[i][]&(G[]^(st-))) !=
||(bir[j][]&(G[]^(st-))) !=
||((bir[i][]<<)&bir[j][]) || ((bir[i][]>>)&bir[j][])) continue;
dp[][j][i] = bir[i][]+bir[j][];
ans = max(ans, dp[][j][i]);
}
}
// printf("___2___%d\n", ans);
int t = ;
for (int i = ; i < n; ++i) {
for (int j = ; j < top && bir[j][] < st; ++j) {
if (bir[j][]&(G[i-]^(st-))) continue;
for (int k = ; k < top && bir[k][] < st; ++k) {
if (bir[k][]&(G[i-]^(st-))) continue;
for (int l = ; l < top && bir[l][] < st; ++l) {
if ( ((G[i]^(st-))&bir[l][])
||(bir[l][]&bir[j][])
||((bir[l][]<<)&bir[k][])
||((bir[l][]>>)&bir[k][])) continue;
dp[t][l][k] = max(dp[t][l][k], dp[(t+)%][k][j]+bir[l][]);
ans = max(ans, dp[t][l][k]);
}
}
}
t = (t+)%;
}
} int main()
{
// freopen("in.txt", "r", stdin);
init(); while (~scanf("%d %d", &n, &m)) {
ans = -;
memset(dp, , sizeof(dp));
for (int i = ; i < n; ++i) {
int p = , tmp;
for (int j = ; j < m; ++j) {
scanf("%d", &tmp);
if(tmp != ) p |= (<<j); ///!!!!
}
G[i] = p;
}
DP();
printf("%d\n", ans);
}
return ;
}
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4539
Hdu 4539 【状态DP】.cpp的更多相关文章
- hdu 4539(状态压缩dp)
题意:曼哈顿距离是指:|x1-x2|+|y1-y2|,只要知道这个概念题意就懂了. 分析:这道题与前面做的几道题有所不同,因为当前行不仅与前一行有关,而且与前两行有关,所以我们开数组的时候还要记录前两 ...
- HDU 4539郑厂长系列故事――排兵布阵(状压DP)
HDU 4539 郑厂长系列故事――排兵布阵 基础的状压DP,首先记录先每一行可取的所哟状态(一行里互不冲突的大概160个状态), 直接套了一个4重循环居然没超时我就呵呵了 //#pragma co ...
- hdu 4614 pieces 状态DP
题意:给你一个长度小于等于16的字符串,每次可以删除一个回文传,问你最少删除干净的字数. 状态+dp dp[i] = min(dp[i],dp[j]+dp[j^i]);(j是i的字串): 连接:htt ...
- hdu 4778 Gems Fight! 博弈+状态dp+搜索
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...
- 【状态DP】 HDU 1074 Doing Homework
原题直通车:HDU 1074 Doing Homework 题意:有n门功课需要完成,每一门功课都有时间期限t.完成需要的时间d,如果完成的时间走出时间限制,就会被减 (d-t)个学分.问:按怎样 ...
- hdu 4352 数位dp + 状态压缩
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 5135(2014广州—状态dp)
t题意:给你n条边,构造任意个三角形,一个三角形恰好只用3条边,每条边只能一次,求面积最大值 思路: 最开始想的是先排序从大到小取,但感觉并不怎么靠谱. 最多12条边,所以可以求出所有可能的三角形面积 ...
- Hdu 3001 Travelling 状态DP
题目大意 一次旅游,经过所有城市至少一次,并且任何一座城市访问的次数不能超过两次,求最小费用 每个城市最多访问两次,用状态0,1,2标识访问次数 把城市1~N的状态按照次序连接在一起,就组成了一个三进 ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
随机推荐
- Codility上的问题 (17) PI 2012
这个题比较简单,给定一个整数数组,对每个元素,求出和它最近比它大的数的距离(下标绝对值),如果没有比它大的数,认为距离是0. 数组元素个数 N [0..50000],数组元素范围[-10^9, +10 ...
- HDU 3068 最长回文 Manacher算法
Manacher算法是个解决Palindrome问题的O(n)算法,能够说是个超级算法了,秒杀其它一切Palindrome解决方式,包含复杂的后缀数组. 网上非常多解释,最好的解析文章当然是Leetc ...
- 微软HR泄露的asp.net面试题
1.面向对象的思想主要包括什么? 2.什么是ASP.net中的用户控件? 3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什么是重载? 4.列举一下你所了解的XML技术及 ...
- 转换函数CONVERSION_EXIT_TSTRN_OUTPUT
CONVERSION_EXIT_TSTRN_OUTPUT 在路线表TVRO中字段TDVZND 运输提前时间,取出来的数值没有转换,需要此函数进行转换.如14400,000 转换后为14,400:00 ...
- 好多NFS的文章
http://www.cnblogs.com/lidabo/category/587288.html http://www.cnblogs.com/lidabo/p/4380555.html
- CImageList类Create函数参数解析
前面提到了CImageList类的Create(...)函数,虽然MSDN上已经有所解释,但仍有网友问到参数的具体含义,下面就我的理解,对参数进行一次轻量级的剖析 函数原型(其他重载函数请参看msdn ...
- ios23- 文件下载(同步和异步)
1.第一步:创建一个单例视图 #import <UIKit/UIKit.h> @interface ios23_downViewController : UIViewController& ...
- 用XCA(X Certificate and key management)可视化程序管理SSL 证书(3)--创建自己定义的凭证管理中心(Certificate Authority)
在第"用XCA(X Certificate and key management)可视化程序管理SSL 证书(2)---创建证书请求"章节中,我们介绍了怎样用XCA创建SSL证书请 ...
- 我在知乎上关于Laser200/310电脑的文章。
我是30年前从Laser-310起步的,我来回答这个问题. 主要硬件规格: CPU:Z-80A/4.7MHz主频 16K RAM + 2K Video RAM 16K ROM 磁带输出:波特率300 ...
- hdu 4455 Substrings (DP 预处理思路)
Substrings Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...