状压DP之炮兵阵地
题目
原题来自:\(NOI 2001\)
司令部的将军们打算在\(N*M\)
的网格地图上部署他们的炮兵部队。一个\(N*M\)的地图由\(N\)行\(M\)列组成,地图的每一格可能是山地(用 H表示),也可能是平原(用 P 表示)。在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队),如果在地图中的灰色所标识的平原上部署一支炮兵部队,它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格。其他位置攻击不到。炮兵的攻击范围不受地形的影响。现在,将军们规划如何部署炮兵部队,在防止误伤的前提下(保证任何两支炮兵部队之间不能互相攻击,即任何一支炮兵部队都不在其他支炮兵部队的攻击范围内),在整个地图区域内最多能够摆放多少我军的炮兵部队。
输入格式
第一行包含两个由空格分割开的正整数,分别表示\(N\)和\(M\);
接下来的\(N\)行,每一行含有连续的\(M\)个字符(P 或者 H),中间没有空格。按顺序表示地图中每一行的数据。
输出格式
仅一行,包含一个整数\(K\),表示最多能摆放的炮兵部队的数量。
样例
样例输入
5 4
PHPP
PPHH
PPPP
PHPP
PHHP
样例输出
6
思路
这道题是一个很有趣的状压DP,由题意可知,对当前状态影响的有当前行状态,上一行状态,以及上上行的状态,对该行都有影响,所以,很显然我们枚举第\(i\)行,\(i-1\)行以及\(i-2\)的状态,对于任意一行(假设为\(i\)),那么我们对第\(i\)行进行合法化判断(仅对当前行),记录合法状态以及数目,方便下面枚举,还需要注意的是地图上的山地,需要单独开一个数组记录,与枚举状态求&,然后我们设\(F\)的三维数组,即\(F[i][j][k]\)代表第i行第j种状态从上一行第k种状态转移过来的最优解,所以有\(f[i][w][k]=max(f[i][w][k],f[i-1][k][j]+Q(w))\),\(f[i][w][k]\)上一状态为\(f[i-1][k][j]\),继承或求较大值更新
如果还是不明白的话,代码奉上
#include<bits/stdc++.h>
using namespace std;
const int maxn=1<<9;
int f[100+10][maxn][maxn];//第i行第j种状态从上一行第k种状态转移过来的最优解
int a[100+10];//记录地图山丘的数量
int state[maxn];//记录合法的状态
int tot,n,m;
int lowbit(int x){//求最低位1
return x&-x;
}
int Q(int x){//判断第x种合法状态下的炮兵个数
x=state[x];
int cnt=0;
for(int i=x;i;i-=lowbit(i))cnt++;
return cnt;
}
bool judge(int x){//判断状态x的合法性
if(x&(x<<1) || x&(x<<2))return 0;
return 1;
}
int main(){
cin>>n>>m;
char ch;
for(int i=1;i<=n;i++){
for(int j=0;j<m;j++){
scanf(" %c ",&ch);
if(ch=='H')a[i]+=(1<<j);//记录山丘位置
}
}
for(int i=0;i<(1<<m);i++){//记录合法状态
if(judge(i))state[++tot]=i;
}
for(int i=1;i<=tot;i++){//初始化第一行i种状态下的最优解,即为当前状态下的炮兵数量
if((a[1] & state[i])==0)f[1][i][1]=Q(i);
}
for(int i=2;i<=n;i++){//枚举第i行
for(int j=1;j<=tot;j++){//i-2行
if(state[j] & a[i-2])continue;//判断第i-2行
for(int k=1;k<=tot;k++){//枚举第i-1行
if(state[k] & a[i-1])continue;//判断第i-1行
if(state[k] & state[j])continue;//判断第i-1行与第i-2行
for(int w=1;w<=tot;w++){
if(state[w] & a[i])continue;//判断第i行
if(state[w] & state[k])continue;//判断第i行和第i-1行
if(state[w] & state[j])continue;//判断第i行和第i-2行
f[i][w][k]=max(f[i][w][k],f[i-1][k][j]+Q(w));//合法情况转移
}
}
}
}
int ans=0;
for(int i=1;i<=tot;i++){//求解
for(int j=1;j<=tot;j++){
if(a[n-1] & state[i])continue;
if(a[n] & state[j])continue;
if(state[i] & state[j])continue;
ans=max(f[n][j][i],ans);
}
}
cout<<ans<<endl;
}
状压DP之炮兵阵地的更多相关文章
- dp乱写1:状态压缩dp(状压dp)炮兵阵地
https://www.luogu.org/problem/show?pid=2704 题意: 炮兵在地图上的摆放位子只能在平地('P') 炮兵可以攻击上下左右各两格的格子: 而高原('H')上炮兵能 ...
- [状压dp]POJ1185 炮兵阵地
中文题 题意不再赘述 对于中间这个“P” 根据dp的无后效性 我们只需考虑前面的 就变成了 只需考虑: 也就是状压前两行 具体与HDOJ的4539类似: 看HDOJ 4539 仅仅是共存状态的判断不同 ...
- 状压DP初识~~炮兵阵地
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 31718 Accepted: 12253 Descriptio ...
- POJ 1185 炮兵阵地(状压DP)
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 26426 Accepted: 10185 Descriptio ...
- [poj1185]炮兵阵地_状压dp
炮兵阵地 poj-1185 题目大意:给出n列m行,在其中添加炮兵,问最多能加的炮兵数. 注释:n<=100,m<=10.然后只能在平原的地方建立炮兵. 想法:第2到状压dp,++.这题显 ...
- TZOJ 4912 炮兵阵地(状压dp)
描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P" ...
- POJ P1185 炮兵阵地 【状压dp】
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 29502 Accepted: 11424 Description 司令 ...
- 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]
题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...
- POJ1185 炮兵阵地 —— 状压DP
题目链接:http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions ...
随机推荐
- Crypto++ AES 加密解密流程
// aesdemo.cpp : 定义控制台应用程序的入口点. // #include <stdio.h>#include <tchar.h>#include <iost ...
- win10系统下office 2019激活
1.新建一个文本文件,创建批处理文件office.bat @echo off (cd /d "%~dp0")&&(NET FILE||(powershell sta ...
- 阿里巴巴二面凉经 flatten扁平化对象与数组
2020-04-13 阿里巴巴二面凉经 flatten扁平化对象与数组 在线笔试的时候写错了一点点 太可惜了哎 还是基础不够扎实... const input = { a: 1, b: [ 1, 2, ...
- grafana repeat 特性
1.设置变量 成功后会自动复制变量值个数的的画图板 类似下图 设置后是不能与预览结果的,需要保存后 切换到其他dashboard 再切换回来就可以看见了 官方文档repeat说明
- @codeforces - 549E@ Sasha Circle
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定两个点集 M 与 S,求是否存在一个圆能够分割两个点集. 原 ...
- python+selenium识别图片验证码
import timeimport pytesseractfrom PIL import Image, ImageEnhancefrom selenium import webdriver url = ...
- (六)logback.xml 配置详解
原文链接:https://www.cnblogs.com/taiyonghai/p/9290641.html,https://blog.csdn.net/A615883576/article/deta ...
- 重学 Java 设计模式:实战命令模式「模拟高档餐厅八大菜系,小二点单厨师烹饪场景」
作者:小傅哥 博客:https://bugstack.cn - 原创系列专题文章 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 持之以恒的重要性 初学编程往往都很懵,几乎在学习的过程中会遇到 ...
- web安全中的session攻击
运行着个简单的demo后,打开login.jsp,使用firebug或chrome会发现,即使没有登录,我们也会有一个JSESSIONID,这是由服务器端在会话开始是通过set-cookie来设置的匿 ...
- springboot集成jpa操作mybatis数据库
数据库如下 CREATE TABLE `jpa`.`Untitled` ( `cust_id` bigint() NOT NULL AUTO_INCREMENT, `cust_address` var ...