POJ1185 炮兵阵地 —— 状压DP
题目链接:http://poj.org/problem?id=1185
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 30608 | Accepted: 11828 |
Description

如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。图上其它白色网格均攻击不到。从图上可见炮兵的攻击范围不受地形的影响。
现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
Input
接下来的N行,每一行含有连续的M个字符('P'或者'H'),中间没有空格。按顺序表示地图中每一行的数据。N <= 100;M <= 10。
Output
Sample Input
5 4
PHPP
PPHH
PPPP
PHPP
PHHP
Sample Output
6
Source
题解:
1.学了轮廓线更新之后,一看到这种棋盘DP就忍不住往轮廓线上想:由于状态转移关系到上两行,所以轮廓线就需要记录两行了,即每一列都需要记录两个格,可知每一列有三种状态,那么用四进制表示。所以复杂度大概为:100*10*(4^10)*2= 很大很大。轮廓线更新都满足不了复杂度要求,那行更新就更加不能满足了吧?能,看下一点。
2.枚举一行的所有状态,因为要求两点间距离>2,所以可以筛掉很多无效状态,最终得到60个有效状态。
3.得到有效状态后,剩下的工作就是典型的状压DP行更新了。复杂度:100*64*64*64。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const double EPS = 1e-;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e5;
const int MAXN = 1e3+; //row记录每一行的可放状态
//sta记录有效状态,cnt记录有效状态有多少个点
//dp[i][j][k]:更新到第i行,且第i-1行的状态为sta[j],第i行的状态为sta[k] 的最大放置数。
int row[], sta[], cnt[MAXN], dp[][][];
int main()
{
int n, m = ;
char str[];
while(scanf("%d%d", &n,&m)!=EOF)
{
for(int i = ; i<=n; i++)
{
scanf("%s", str);
row[i] = ;
for(int j = ; j<m; j++)
row[i] += (str[j]=='H')*(<<j);
} int tot = ;
for(int s = ; s<(<<m); s++)
{
if( !(s&(s<<)) && !(s&(s<<)) )
{
sta[++tot] = s;
cnt[tot] = ;
for(int j = ; j<m; j++)
if(s&(<<j))
cnt[tot]++;
}
} memset(dp, , sizeof(dp));
for(int i = ; i<=n; i++)
{
for(int j = ; j<=tot; j++)
{
int s1 = sta[j];
if(i> && (s1&row[i-])) continue;
for(int k = ; k<=tot; k++)
{
int s2 = sta[k];
if(i> && (s2&row[i-])) continue;
if(s1&s2) continue;
for(int t = ; t<=tot; t++)
{
int s3 = sta[t];
if(s3&row[i]) continue;
if((s1&s3)||(s2&s3)) continue;
dp[i][k][t] = max(dp[i][k][t], dp[i-][j][k]+cnt[t]);
}
}
}
} int ans = ;
for(int i = ; i<=tot; i++)
for(int j = ; j<=tot; j++)
ans = max(ans, dp[n][i][j]);
printf("%d\n", ans);
}
}
POJ1185 炮兵阵地 —— 状压DP的更多相关文章
- poj1185 炮兵阵地 状压dp
司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示) ...
- TZOJ 4912 炮兵阵地(状压dp)
描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P" ...
- 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]
题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...
- [POJ1185][NOI2001]炮兵阵地 状压DP
题目链接:http://poj.org/problem?id=1185 很裸的状压,考虑对于一行用二进制储存每一种的状态,但是状态太多了做不了. 观察到有很多状态都是不合法的,于是我们预处理出合法的状 ...
- poj - 1185 炮兵阵地 状压DP 解题报告
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 21553 Accepted: 8363 Description ...
- luogu 2704 炮兵阵地 状压dp
状压的基础题吧 第一次看感觉难上天,后来嘛就.. 套路:先根据自身状态筛出可行状态,再根据地图等其他限制条件筛选适合的状态加入答案 f i,j,k 分别代表 行数,本行状态,上行状态,再累加答案即可 ...
- POJ 1185 炮兵阵地 状压dp
题目链接: http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K 问题描述 司令部的将军们打算在N*M ...
- [NOI2001]炮兵阵地 状压DP
题面: 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图.在每一格平原地形上最多 ...
- 炮兵阵地 /// 状压DP oj26314
题目大意: 炮兵阵地 设置炮兵的位置 其上两位 下两位 左两位 右两位 不能同时设置炮兵 这题是 corn fields玉米地 的升级版 可以先看下这题的注释 更详细些 第一种方法是网上大多数题解的解 ...
随机推荐
- 自编自演的Linux脚本
启动全服务脚本 #!/bin/bash cd `` BIN_DIR=`pwd` COUNT= function deal(){ # ; #/stdout.log |grep -w 'Main serv ...
- spring batch的使用和定时器Quart的使用
Spring Batch是一个基于Spring的企业级批处理框架,它通过配合定时器Quartz来轻易实现大批量的数据读取或插入,并且全程自动化,无需人员管理. 在使用spring batch之前,得对 ...
- apache支持php
#tarzxvf php-5.2.9.tar.gz #cdphp-5.2.9 #./configure--prefix=/usr/local/php --with-apxs2=/usr/local/a ...
- 【Excle数据透视】如何创建一个数据透视表
数据透视表可以汇总.分析.浏览和提供工作表数据或外部数据源的汇总数据 创建方法一 通过”插入”创建,具体操作请看下图: 创建方法二 通过快捷键创建 使用[ALT+D+P]创建 首先按下alt键,然后依 ...
- Sql 复习3之存储管理
一.事务管理 单个工作单元称为事务,我们将若干条sql命令组合在一起,形成存储过程.触发器等,利用存储过程和触发器可以进行事务管理. 二.编程基础介绍 主要有:函数.程序设计语句等. 程序设计语句: ...
- php excel文件导出之二 图像导出
PHP文件导出 之图像 和 文字同一时候导出 事实上之前写了个php文件导出.跟这个极为相似,由于项目须要对图像进行导出.查询一番.又写了一个, 这个能实现图像的导出(仅仅能是本地图像,不能使用远程图 ...
- HttpClient 模拟登录网易微博
实现核心:代码执行流程,根据抓包工具,模拟浏览器请求步骤走 private static void testLogin() { try ...
- HDU 2242 考研路茫茫——空调教室(边双连通)
HDU 2242 考研路茫茫--空调教室 题目链接 思路:求边双连通分量.然后进行缩点,点权为双连通分支的点权之和,缩点完变成一棵树,然后在树上dfs一遍就能得出答案 代码: #include < ...
- CSS3 实现背景透明,文字不透明,兼容所有浏览器
<!DOCTYPE html><html><head><meta charset="utf-8"><title>opac ...
- oracle不同用户间访问表不添加用户名(模式)前缀
默认的情况下,oracle里面的用户A,要访问用户B的表需要带用户B的前缀,如访问用户B的 user表,需要这样访问 select * from B.user;如果想要不添加用户前缀,需要这样处理: ...