P2704 [NOI2001] 炮兵阵地
泪目,调了一下午的状压,强推,思维很纯粹
- [P2704 [NOI2001] 炮兵阵地](https://www.luogu.com.cn/problem/P2704)
希望你不认识她≥ω≤
题目大意:给一个n*m的图,然后其中有两种地形(H,P),平原地形(P)可以放置棋子,不同棋子之间存在制约关系,如下图
黑色的地形不可以放置,问最多可以放置多少个棋子。
分析地形:二维数组,0表示P,1表示H。
说说思路:因为每个位置存在两种情况(放置棋子/不放棋子),所以每种放置情况可以转化成一个二进制数,且m<10,最多存在(1<10)种状态。考虑限制条件后如下
int ghs(int h){//二进制数找有几个1int ss=0;while(h!=0){if(h&1)ss++;//位运算最后一位h=h>>1;//除以2}return ss;//返回当前状态的权重
} for(int i=1;i<(1<<m);i++){//以二进制枚举所有的可能if(i&(i>>1)||i&(i>>2)||i&(i<<1)||i&(i<<2))continue;//已有‘1’左右两边不能放置st[++num]=i;//num状态int cpi=i;s[num]=ghs(cpi);
}
当(状态和地形)(状态和状态)进行&运算==0时,说明状态可以存在。需要提前枚举前两行。
状态受前两行分布的棋子影响。
写出递推式:dp[第i行][当前状态][上一行的状态]=max(dp[第i行][当前状态][上一行的状态],dp[上一行][上一行的状态][再上一行的状态](ps:这里最开始没明白状态枚举为什么是上一行而不是上两行,仔细观察递推式其实是因为至少回溯两行,判断条件需要上两行的状态,for的时候需要返回上一行判断,并加上这一行的权重)
for(int i=1;i<=num;i++){//第一行if((st[i]&f[1])==0){//状态匹配dp[1][i][0]=s[i];}}//cout<<"yes"<<endl;for(int i=1;i<=num;i++){if((st[i]&f[2])==0){for(int j=1;j<=num;j++){if((st[i]&st[j])==0&&(st[j]&f[1])==0){dp[2][i][j]=s[i]+s[j];}}}}for(int i=3;i<=n;i++){//第n行for(int j=1;j<=num;j++){//枚举状态if((st[j]&f[i])==0){for(int p1=1;p1<=num;p1++){//上一行if((st[j]&st[p1])==0&&(st[p1]&f[i-1])==0){for(int p2=1;p2<=num;p2++){//再上一行if((st[j]&st[p2])==0&&(st[p1]&st[p2])==0&&(st[p2]&f[i-2])==0){dp[i][j][p1]=max(dp[i][j][p1],dp[i-1][p1][p2]+s[j]);}}}}}}}
最后ac代码如下:
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[105][105],f[105],st[105],s[205],dp[105][105][105];
//a:图的输入 f:换算成二进制数的图 st:枚举所有的状态 s:状态所对应的每行权重 int ghs(int h){int ss=0;while(h!=0){if(h&1)ss++;h=h>>1;}return ss;
}
int main(){cin>>n>>m;char tmp;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>tmp;if(tmp=='H')a[i][j]=1;}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){f[i]=(f[i]<<1)+a[i][j];}}int num=0;st[++num]=0;for(int i=1;i<(1<<m);i++){if(i&(i>>1)||i&(i>>2)||i&(i<<1)||i&(i<<2))continue;st[++num]=i;int cpi=i;s[num]=ghs(cpi);}for(int i=1;i<=num;i++){//第一行if((st[i]&f[1])==0){//状态匹配dp[1][i][0]=s[i];}}//cout<<"yes"<<endl;for(int i=1;i<=num;i++){if((st[i]&f[2])==0){for(int j=1;j<=num;j++){if((st[i]&st[j])==0&&(st[j]&f[1])==0){dp[2][i][j]=s[i]+s[j];}}}}for(int i=3;i<=n;i++){//第n行for(int j=1;j<=num;j++){//枚举状态if((st[j]&f[i])==0){for(int p1=1;p1<=num;p1++){//上一行if((st[j]&st[p1])==0&&(st[p1]&f[i-1])==0){for(int p2=1;p2<=num;p2++){//再上一行if((st[j]&st[p2])==0&&(st[p1]&st[p2])==0&&(st[p2]&f[i-2])==0){dp[i][j][p1]=max(dp[i][j][p1],dp[i-1][p1][p2]+s[j]);}}}}}}}int ans=0;for(int i=1;i<=num;i++){for(int j=1;j<=num;j++){ans=max(ans,dp[n][i][j]);}}cout<<ans<<endl;
}//泪目
最近在按照洛谷的dp状压题单刷,大概每天一题吧,等到十一的周末(不放假555555)通过最近做过的题总结一下状压的基本思路和要点。之后会进行其他dp的练习。
目前会一点的dp:
1、各种背包
2、环形(环状)dp
3、树形dp
4、乱搞dp(我愿称之为shi上雕花)
P2704 [NOI2001] 炮兵阵地相关推荐
- C++ 洛谷 P2704 [NOI2001]炮兵阵地
P2704 [NOI2001]炮兵阵地 没学状压DP的看一下 此题意思很简单,如下图,就是十字架上的不能有两个点放炮兵. 在做此题前,先做一下玉米田 玉米田题解 分析: 而m即一行的个数小于等于10, ...
- 洛谷 P2704 [NOI2001]炮兵阵地
题目 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P& ...
- 洛谷P2704 [NOI2001]炮兵阵地(状压dp)
题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P&quo ...
- jzoj1768,P2704,POJ1185-[NOI2001]炮兵阵地【状态压缩dp】
正题 POJ链接:http://poj.org/problem?id=1185 jzoj链接:https://jzoj.net/senior/#main/show/1768 洛谷评测记录:https: ...
- [NOI2001]炮兵阵地
Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示), 也可能是平原(用&q ...
- 洛谷 P2704 炮兵阵地 题解
洛谷 P2704 炮兵阵地 题解 洛谷 P2704 题目 司令部的将军们打算在NNNMMM的网格地图上部署他们的炮兵部队.一个NNNMMM的地图由NNN行MMM列组成,地图的每一格可能是山地(用&qu ...
- 2022-5-20 吃月饼(something wrong), 数塔取数问题, 制铁棒, 子段统计, 炮兵阵地
1. 吃月饼 有一块月饼,是正三角形的,又被分割成了许多块小正三角形的月饼,里面有若干块被吃掉了.现在想要在这块月饼中再找一个由小正三角形月饼的正三角形月饼,而且要求面积最大的. 样例解释: 大月饼的 ...
- POJ 1185 炮兵阵地 (状压DP)
炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14869 Accepted: 5575 Description ...
- hdu4539 郑厂长系列故事——排兵布阵 + POJ1158 炮兵阵地
题意: 郑厂长系列故事--排兵布阵 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Other ...
- poj 1185 NYOJ 85 炮兵阵地(状态压缩dp)
炮兵阵地 时间限制:2000 ms | 内存限制:65535 KB 难度:6 描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地 ...
最新文章
- 贵州大学明德学院计算机有多少班级,2014年贵州大学明德学院算机科学及信息系电子信息工程专业介绍...
- CSDN开源夏令营 百度数据可视化实践 ECharts(8)
- Linux驱动编程 step-by-step (十一)
- Core Data 编程指南
- pre2-flink单机部署与job提交
- 运行时间_运行一段时间报高压保护
- Linq to SQL 语法记录....并发写事务
- java 编辑器 开发工具_好的程序员有哪些实用的HTML5开发工具可以选择?
- java 路径不存在则创建_java中判断目录是否存在,若不存在则创建
- git 总是要求输入密码的问题
- FANUC NC GUIDE PRO 17.1虚拟机(XP系统)
- 多益网络校招 —— web前端笔试题
- hao916,hao123,2345.com浏览器劫持-分析与清除
- 再谈微软复兴,纳德拉与库克、马斯克、皮查伊在管理上有什么不同
- 荣耀4a鸿蒙,赵明:6 月起芯片供应将全面恢复,荣耀未来会考虑用华为鸿蒙系统...
- linux搭建web服务
- MySql生成日历表
- 关于死锁你了解多少,通过“让APP随手机壳改变颜色,程序员和产品经理大家”这一事,了解下死锁可好?
- 实验任务(五)---综合渗透
- 三菱串口PLC远程下载程序案例