炮兵阵地(POJ 1185状压dp)
题意:n*m地图'H'能放'p'不能放,布兵的方格上下左右不能布兵,给你地图求最大布兵数
分析:关系到前两行,所以dp[i][j][k]第i行状态为j,i-1行状态为k时的最大布兵数, 先求出所有可行的状态,统计出其布兵数。
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <queue>
#include <stack>
#include <cstdio>
#include <vector>
#include <string>
#include <cctype>
#include <complex>
#include <cassert>
#include <utility>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef long long ll;
#define lson l,m,rt<<1
#define pi acos(-1.0)
#define rson m+1,r,rt<<11
#define All 1,N,1
#define read freopen("in.txt", "r", stdin)
const ll INFll = 0x3f3f3f3f3f3f3f3fLL;
const int INF= 0x7ffffff;
const int mod = 1000000007;
int n,m,a[200],dp[110][200][200];
int num,sum[2000],cas[2000];
bool judge(int x){
return ((x<<1)&x)||((x<<2)&x)||((x>>1)&x)||((x>>2)&x);
}
int countnum(int x){
int t=0;
while(x){
if(x&1)t++;
x>>=1;
}
return t;
}
//求预处理所有可能的状态
void init(){
num=0;
for(int i=0;i<(1<<m);++i){
if(!judge(i)){
cas[num]=i;
sum[num++]=countnum(i);
}
}
}
void solve(){
init();
memset(dp,0,sizeof(dp));
for(int i=0;i<num;++i){
if(a[0]&cas[i])continue;
dp[0][i][0]=sum[i];
}
for(int i=1;i<n;++i){
//枚举当前状态
for(int j=0;j<num;++j){
if(cas[j]&a[i])continue;
//枚举符合条件的上一行状态
for(int k=0;k<num;++k){
if(cas[k]&a[i-1])continue;
if(cas[k]&cas[j])continue;
int maxv=-1;
for(int l=0;l<num;++l){
if((cas[l]&cas[k])||(cas[l]&cas[j]))continue;
maxv=max(maxv,dp[i-1][k][l]);
}
dp[i][j][k]=maxv+sum[j];
}
}
}
int maxn=-1;
for(int i=0;i<num;++i)
for(int j=0;j<num;++j){
maxn=max(maxn,dp[n-1][i][j]);
}
printf("%d\n",maxn);
}
int main()
{
char ch;
while(~scanf("%d%d",&n,&m)){
memset(a,0,sizeof(a));
for(int i=0;i<n;++i)
for(int j=0;j<m;++j){
cin>>ch;
if(ch=='H'){
a[i]|=(1<<j);
}
}
solve();
}
return 0;
}
炮兵阵地(POJ 1185状压dp)的更多相关文章
- poj 1185 状压dp+优化
http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 291 ...
- poj 1185(状压dp)
题目链接:http://poj.org/problem?id=1185 思路:状态压缩经典题目,dp[i][j][k]表示第i行状态为j,(i-1)行状态为k时最多可以放置的士兵个数,于是我们可以得到 ...
- 状压dp(B - 炮兵阵地 POJ - 1185 )
题目链接:https://cn.vjudge.net/contest/276236#problem/B 题目大意:略 具体思路:和我的上一篇写状压dp的思路差不多,不过就是这个题相当于上一个题的升级 ...
- POJ 3254 (状压DP) Corn Fields
基础的状压DP,因为是将状态压缩到一个整数中,所以会涉及到很多比较巧妙的位运算. 我们可以先把输入中每行的01压缩成一个整数. 判断一个状态是否有相邻1: 如果 x & (x << ...
- poj 1170状压dp
题目链接:https://vjudge.net/problem/POJ-1170 题意:输入n,表示有那种物品,接下来n行,每行a,b,c三个变量,a表示物品种类,b是物品数量,c代表物品的单价.接下 ...
- hdu 1185 状压dp 好题 (当前状态与上两行有关系)
/* 状压dp 刚开始&写成&&看了好长时间T0T. 状态转移方程 dp[i][k][j]=Max(dp[i][k][j],dp[i-1][l][k]+num[i][j]);( ...
- POJ 3254 状压DP
题目大意: 一个农民有一片n行m列 的农场 n和m 范围[1,12] 对于每一块土地 ,1代表可以种地,0代表不能种. 因为农夫要种草喂牛,牛吃草不能挨着,所以农夫种菜的每一块都不能有公共边. ...
- POJ 2411 状压DP经典
Mondriaan's Dream Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 16771 Accepted: 968 ...
- poj 3254 状压dp入门题
1.poj 3254 Corn Fields 状态压缩dp入门题 2.总结:二进制实在巧妙,以前从来没想过可以这样用. 题意:n行m列,1表示肥沃,0表示贫瘠,把牛放在肥沃处,要求所有牛不能相 ...
随机推荐
- cojs 火龙果 解题报告
昨天晚上做了一发HNOI,感觉有很多新的idea 于是就选了一个出成题目辣 我们考虑暴力 暴力很明显是把这个图A<=D,B<=E的形态搞出来 之后处理相关的询问 这样我们会很容易得到正解: ...
- 李洪强iOS开发之OC[014] -对象的存储细节
// // main.m // 13 - 对象的存储细节 // // Created by vic fan on 16/7/9. // Copyright © 2016年 李洪强. All r ...
- Java多线程3:Thread中start()和run()的区别
原文:http://www.cnblogs.com/skywang12345/p/3479083.html start() 和 run()的区别说明start():它的作用是启动一个新线程,新线程会执 ...
- 80. Remove Duplicates from Sorted Array II
题目: Follow up for "Remove Duplicates":What if duplicates are allowed at most twice? For ex ...
- Android Service和广播
前言: 我们都知道Android的四大基本组件:Activity.ContentProvider.Service以及BroadcastReceiver,前面的两个我们在前几篇已经具体讲解了,今天这一天 ...
- Objective-c CoreData
#import "AppDelegate.h" #import "Person.h" @implementation AppDelegate @synthesi ...
- toad for sqlserver5.7
toad for sqlserver5.7 虽然SSMS很好很强大,不过有时候使用一些第三方工具可以使MSSQL DBA们更加的方便管理MSSQL toad for sqlserver5.7就是这样一 ...
- C++ STL之查找算法
C++STL有好几种查找算法,但是他们的用法上有很多共同的地方: 1.除了binary_search的返回值是bool之外(查找的了返回true,否则返回false),其他所有的查找算法返回值都是一个 ...
- Parallel WebDriver executions using TestNG
In this post, we will see how does one make use of TestNG to kick off parallel UI tests using WebDri ...
- LinuxShell算术运算
Bash shell 的算术运算有四种方式:1:使用 expr 外部程式 加法 r=`expr 4 + 5`echo $r注意! '4' '+' '5' 这三者之间要有空白r=`expr 4 * 5` ...