题目大意:中文题目就不多说大意了

解题思路:

1.每行最多仅仅有十个位置,且不是山地就是平原,那么就能够用1表示山地,0表示平原,将每一行的状态进行压缩了

2.接着找出每行能放炮兵的状态。先不考虑其它行放炮兵和该行的山地对其造成的影响,枚举出全部的状态。并记录每一个状态下放的炮兵数量

在上述情况下放炮兵。仅仅须要考虑同行的炮兵是否会相互攻击就能够了,那仅仅须要推断他的左边第一个位置是否有炮兵和左边第二个位置是否有炮兵就可以

3.接着进行dp,由于影响因素有两个。一个是上一行的状态,还有一个是上两行的状态,所以设dp[row][i][j]为第row行,放置状态为i,第row-1行,放置状态为j的情况下所能放的最多炮兵数量

可得到转移方程,在前两行不影响该行放置的

dp[row][i][j] = max(dp[row][i][j], dp[row-1][j][k] + i状态下能放置的炮兵数)

參考了这位大神的代码,写得很得具体这里写链接内容

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 110
#define maxm 20
#define maxs 70
int R, C, cnt;
char str[15];
int row[maxn], num[maxn], statu[maxn];
int dp[maxn][maxs][maxs]; void input() { memset(row, 0, sizeof(row));
for(int i = 0; i < R; i++) {
scanf("%s", str);
for(int j = 0; j < C; j++)
if(str[j] == 'H')
row[i] += (1 << j);
}
} void init_statu() { memset(num, 0, sizeof(num));
cnt = 0;
for(int i = 0; i < (1 << C); i++) {
if((i & (i << 1)) || (i & (i << 2)))
continue;
int t = i;
while(t) {
num[cnt] += (t & 1);
t >>= 1;
}
statu[cnt++] = i;
}
} void init_DP() { memset(dp, 0, sizeof(dp));
for(int i = 0; i < cnt; i++) {
if(statu[i] & row[0])
continue;
dp[0][i][0] = num[i];
} for(int i = 0; i < cnt; i++) {
if(statu[i] & row[1])
continue; for(int j = 0; j < cnt; j++) {
if(statu[j] & row[0])
continue;
if(statu[i] & statu[j])
continue;
dp[1][i][j] = max(dp[1][i][j], dp[0][j][0] + num[i]);
}
}
} int solve() {
for(int r = 2; r < R; r++) {
for(int i = 0; i < cnt; i++) {
if(statu[i] & row[r])
continue;
for(int j = 0; j < cnt; j++) {
if(statu[j] & row[r - 1])
continue;
if(statu[i] & statu[j])
continue;
for(int k = 0; k < cnt; k++) {
if(statu[k] & statu[j])
continue;
if(statu[k] & statu[i])
continue;
if(statu[k] & row[r - 2])
continue;
dp[r][i][j] = max(dp[r][i][j], dp[r - 1][j][k] + num[i]);
}
}
}
}
int ans = 0;
for(int i = 0; i < cnt; i++)
for(int j = 0; j < cnt; j++)
ans = max(ans, dp[R-1][i][j]);
return ans;
} int main() {
while(scanf("%d%d", &R, &C) != EOF) {
input();
init_statu();
init_DP();
printf("%d\n", solve());
}
return 0;
}

POJ - 1185 炮兵阵地 (状态压缩)的更多相关文章

  1. poj 1185 炮兵阵地 状态压缩dp

    思路:定义一个三维数组dp[x][i][j]其中x为now和pre两种状态,now表示当前两行最优解,pre表示出了本行外,前两行的最优解.那么状态转移方程为 dp[now][j][k]=max(dp ...

  2. POJ 3254 炮兵阵地(状态压缩DP)

    题意:由方格组成的矩阵,每个方格可以放大炮用P表示,不可以放大炮用H表示,求放最多的大炮,大炮与大炮间不会互相攻击.大炮的攻击范围为两个方格. 分析:这次当前行的状态不仅和上一行有关,还和上上行有关, ...

  3. POJ 1185 炮兵阵地 状压dp

    题目链接: http://poj.org/problem?id=1185 炮兵阵地 Time Limit: 2000MS Memory Limit: 65536K 问题描述 司令部的将军们打算在N*M ...

  4. POJ 1185 炮兵阵地(动态规划+状态压缩)

    炮兵阵地 Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原( ...

  5. POJ 1185 炮兵阵地 经典的 状态压缩dp

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 16619   Accepted: 6325 Description ...

  6. POJ 1185 炮兵阵地(经典的状态压缩DP)

    题意:中文题. 思路,经典的状态压缩题目. 由于列长比较小,我们可以以行为阶段用状态压缩来做. 由于攻击只占两个格,这样从行的角度看,第i行的炮兵只与前i-1和前i-2行有关系.这样如果用j,k,l分 ...

  7. POJ 1185 炮兵阵地 (状态压缩DP)

    题目链接 Description 司令部的将军们打算在NM的网格地图上部署他们的炮兵部队.一个NM的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用& ...

  8. poj 1185 炮兵阵地 [经典状态压缩DP]

    题意:略. 思路:由于每个大炮射程为2,所以如果对每一行状态压缩的话,能对它造成影响的就是上面的两行. 这里用dp[row][state1][state2]表示第row行状态为state2,第row- ...

  9. POJ 1185 炮兵阵地(状压DP)

    炮兵阵地 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26426   Accepted: 10185 Descriptio ...

随机推荐

  1. 链接分析算法之:HITS算法

    链接分析算法之:HITS算法     HITS(HITS(Hyperlink - Induced Topic Search) ) 算法是由康奈尔大学( Cornell University ) 的Jo ...

  2. HDFS写入和读取流程

    HDFS写入和读取流程 一.HDFS HDFS全称是Hadoop Distributed System.HDFS是为以流的方式存取大文件而设计的.适用于几百MB,GB以及TB,并写一次读多次的场合.而 ...

  3. 剖析MFC六大关键技术(五六)--消息映射与命令传递

    说到消息,在MFC中,“最熟悉的神秘”可算是消息映射,那是我们刚开始接触MFC时就要面对的东西.有过SDK编程经验的朋友转到MFC编程的时候,一下子觉得什么都变了样.特别是窗口消息及对消息的处理跟以前 ...

  4. 关于String.concat()方法和StringBuffer.append()方法的学习:方法是如何追加字符到源字符串的

    问题分析: 首先,看看两段代码的运行结果,两段代码分别是: 第一段代码,关于String.concat()方法的测试: public static void main(String[] args) { ...

  5. Codeforces Round #200 (Div. 2) C. Rational Resistance

    C. Rational Resistance time limit per test 1 second memory limit per test 256 megabytes input standa ...

  6. Python用subprocess的Popen来调用系统命令

    当我们须要调用系统的命令的时候,最先考虑的os模块.用os.system()和os.popen()来进行操作.可是这两个命令过于简单,不能完毕一些复杂的操作,如给执行的命令提供输入或者读取命令的输出, ...

  7. java 简单的数据增删该查

    import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sq ...

  8. Activity的onSaveInstanceState()和onRestoreInstanceState()以及API详解

    为了弄清楚onSaveInstanceState()方法和onRestoreInstanceState()方法,我翻译一下谷歌的API,翻译如下: There are a few scenarios ...

  9. BZOJ 1648: [Usaco2006 Dec]Cow Picnic 奶牛野餐( dfs )

    直接从每个奶牛所在的farm dfs , 然后算一下.. ----------------------------------------------------------------------- ...

  10. QDebug &operator<<出错(根据QString来找,是不得要领的,而是应该根据QString所在的对象来思考)

    程序运行后,总是崩溃在这个地方:inline QDebug &operator<<(const QString & t) 我应该用什么办法找出是哪个QString出了问题呢 ...