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

解题思路:

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. AnsiString 在 Delphi 中虽然不可用,但是,在 C++ 中可以用

    [C++] C++ Builder 中 Ansi 编码的字符串在Android/iOS程序中显示的问题 呃,这个问题说起来,其实也不麻烦,C++ Builder 本身在 TEncoding 做了处理, ...

  2. FMDB 的基本操作

    在FMDB下载文件后,工程中必须导入如下文件,并使用 libsqlite3.dylib 依赖包 FMDB同时兼容ARC和非ARC工程,会自动根据工程配置来调整相关的内存管理代码. FMDB常用类: F ...

  3. Average(模拟)

      Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Tota ...

  4. 探索Android中的Parcel机制(上)

    一.先从Serialize说起 我们都知道JAVA中的Serialize机制,译成串行化.序列化……,其作用是能将数据对象存入字节流其中,在须要时又一次生成对象.主要应用是利用外部存储设备保存对象状态 ...

  5. MFC下的日历表

    // CalenderDlg.h : header file // #if !defined(AFX_CALENDERDLG_H__8DC8F113_2A47_45B8_8266_75CB406D68 ...

  6. STL之Queue(Q)

    STL的Queue(数据结构中的队列): 特点:FIFO 先进先出: 自适应容器(即容器适配器)   栈适配器STL queue  STL中实现的Queue: 用list来实现queue: queue ...

  7. 【Oracle】ORA-01722:无效数字(控制文件最后一个字段)

    原因: 每一行物理数据最后都存在一个换行符. 如果integer或者number类型的字段位于控制文件的最后,最后其实都会有CR/LF的换行符,在用sqlldr导入时会把换行符也算作那个数字的一部分, ...

  8. [Swust OJ 643]--行列式的计算(上三角行列式变换)

    题目链接:http://acm.swust.edu.cn/problem/643/ Time limit(ms): 1000 Memory limit(kb): 65535   Description ...

  9. BZOJ 3155: Preprefix sum( 线段树 )

    刷刷水题... 前缀和的前缀和...显然树状数组可以写...然而我不会, 只能写线段树了 把改变成加, 然后线段树维护前缀和, 某点p加, 会影响前缀和pre(x)(p≤x≤n), 对[p, n]这段 ...

  10. Unbuntu 14.04 下chrome browser bookmark 显示中文乱码解决方案

    来源:http://blog.csdn.net/loveaborn/article/details/29579787 网上有人给出这个问题的解决是通过修改文件/etc/fonts/conf.d/49- ...