POJ 3254 炮兵阵地(状态压缩DP)
题意:由方格组成的矩阵,每个方格可以放大炮用P表示,不可以放大炮用H表示,求放最多的大炮,大炮与大炮间不会互相攻击。大炮的攻击范围为两个方格。
分析:这次当前行的状态不仅和上一行有关,还和上上行有关,所以用三维dp【i】【j】【k】来表示第i行的状态为j,i-1行状态为k时最多的大炮。
一开始看数据量为100 * 1024 * 1024 铁定要爆,但是由于大炮的攻击方式,单独看每一行最多只有几十种可行的状态,所以保存好这些状态就行了。
#include <cstdio>
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
int n,m,sum;
int dp[105][1 << 7][1 << 7]; // dp【i】【j】【k】来表示第i行的状态为j,i-1行状态为k时最多的大炮
int buff[1 << 6]; // 存状态
int bar[105]; // 存障碍
int num[1 << 6]; // 存每种状态中1的个数,即为大炮的个数
char map[105][11];
void init() {
memset(bar,0,sizeof(bar));
memset(dp,0,sizeof(dp));
memset(buff,0,sizeof(buff));
memset(num,0,sizeof(num));
sum = 0;
}
void barrier() {
for(int i=0; i<n; i++) {
for(int j=0; j<m; j++) {
if(map[i][j] == 'H') {
int move = m - j - 1;
bar[i] += (1 << move);
}
}
}
} bool judge(int s) {
while(s) {
if(s & 1) {
if(((s >> 1) & 1) || ((s >> 2) & 1)) return false;
}
s = s >> 1;
}
return true;
} void getbuff() {
int total = 1 << m;
for(int i=0; i<total; i++) {
if(judge(i)) buff[sum++] = i;
}
} int cal(int s) {
int cnt = 0;
while(s) {
if(s & 1) cnt ++;
s = s >> 1;
}
return cnt;
} void getnum() {
for(int i=0; i<sum; i++) {
num[i] = cal(buff[i]);
}
}
int main() {
scanf("%d%d",&n,&m);
init();
for(int i=0; i<n; i++) scanf("%s",map[i]);
barrier();
getbuff();
getnum();
for(int i=0; i<n; i++) {
for(int j=0; j<sum; j++) {
if(bar[0] & buff[j]) continue;
for(int k=0; k<sum; k++) {
dp[0][j][k] = num[j];
}
}
}
for(int i=1; i<n; i++) {
for(int j=0; j<sum; j++) {
if(bar[i] & buff[j]) continue;
for(int k=0; k<sum; k++) {
if(bar[i-1] & buff[k]) continue;
if((buff[j] & buff[k])) continue;
for(int l=0; l<sum; l++) {
if(i != 1) {
if(bar[i-2] & buff[l]) continue;
if(buff[k] & buff[l] || buff[j] & buff[l]) continue;
}
dp[i][j][k] = max(dp[i][j][k],
dp[i-1][k][l] + num[j]);
}
}
}
}
int ans = 0;
for(int i=0; i<n; i++) {
for(int j=0; j<sum; j++) {
for(int k=0; k<sum; k++) {
ans = max(ans,dp[i][j][k]);
}
}
}
printf("%d\n",ans);
return 0;
}
POJ 3254 炮兵阵地(状态压缩DP)的更多相关文章
- poj 1185 炮兵阵地 状态压缩dp
思路:定义一个三维数组dp[x][i][j]其中x为now和pre两种状态,now表示当前两行最优解,pre表示出了本行外,前两行的最优解.那么状态转移方程为 dp[now][j][k]=max(dp ...
- POJ1185 - 炮兵阵地(状态压缩DP)
题目大意 中文的..直接搬过来... 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平 ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- POJ 3254 Corn Fields (状态压缩DP)
题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案). 分析:方格边长范围只有12,用状态压缩dp好解决. 预处理:每一行的障碍用一个状态 ...
- POJ 3254. Corn Fields 状态压缩DP (入门级)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9806 Accepted: 5185 Descr ...
- POJ 3254 Corn Fields 状态压缩DP (C++/Java)
id=3254">http://poj.org/problem? id=3254 题目大意: 一个农民有n行m列的地方,每一个格子用1代表能够种草地,而0不能够.放牛仅仅能在有草地的. ...
- POJ - 1185 炮兵阵地 (状态压缩)
题目大意:中文题目就不多说大意了 解题思路: 1.每行最多仅仅有十个位置,且不是山地就是平原,那么就能够用1表示山地,0表示平原,将每一行的状态进行压缩了 2.接着找出每行能放炮兵的状态.先不考虑其它 ...
- poj - 3254 Corn Fields (状态压缩dp入门)
http://poj.org/problem?id=3254 参考:http://blog.csdn.net/accry/article/details/6607703 农夫想在m*n的土地上种玉米, ...
- POJ 3254 Corn Fields状态压缩DP
下面有别人的题解报告,并且不止这一个状态压缩题的哦···· http://blog.csdn.net/accry/article/details/6607703 下面是我的代码,代码很挫,绝对有很大的 ...
随机推荐
- openssl 非对称加密算法RSA命令详解
1.非对称加密算法概述 非对称加密算法也称公开密钥算法,其解决了对称加密算法密钥分配的问题,非对称加密算法基本特点如下: 1.加密密钥和解密密钥不同 2.密钥对中的一个密钥可以公开 3.根据公开密钥很 ...
- Linux的用户和组
1. 查看配置文件/etc/shadow第一行中root账号的第三个字段(以':'分隔)中的数字,请算一下这个数字是怎么来的?距离1970年1月1日到上次更改密码的时间的间隔天数.例如root密码日期 ...
- sql 读取excel中的数据
select 列名 as 字段名 from openBowSet('MSDASQL.1','driver=Microsoft Excel Driver(*.xls);dbq=文件存放地址','sele ...
- 让qq图标在自己的网站上显示方法
代码如下: <div id="xixi" onmouseover="toBig()" style="top: 260px; left: 5px; ...
- css导航条
#nav ul { display: none; position: absolute; padding-top: 0px;} #nav li:hover ul { display: block;}
- VS2010 rdlc 被除数为0 显示错误号
=Sum(Fields!ROCKNUM.Value/Fields!SEND.Value*100) 当Fields!SEND.Value为0或者空时,显示错误号 修改: =IIF(isnothing(F ...
- 3D图片采集与展示(SurfaceView 自适应 Camera, 录制视频, 抽取帧)
最近在做一个3D图片采集与展示. 主要功能为:自定义Camera(google 已经摈弃了Camera, 推荐使用Camera2,后续篇幅,我将会用Camera2取代Camera),围绕一个物体360 ...
- 删除作业计划出错(DELETE语句与 REFERENCE约束"FK_subplan_job_id"冲突。)
删除作业计划出错(DELETE语句与 REFERENCE约束"FK_subplan_job_id"冲突.) use msdb select * from sysmaintplan_plans --查看 ...
- C# 几十万级数据导出Excel,及Excel各种操作
先上导出代码 /// <summary> /// 导出速度最快 /// </summary> /// <param name="list">&l ...
- C++友元函数重载"++"和"--"运算符
代码: #include <iostream> #include <cstring> using namespace std; class one{ public: one(i ...