您的位置:首页 > 其它

poj 1185 炮兵阵地 (状态压缩dp~)

2017-11-15 10:50 441 查看
为什么row数组要存着H的值而不是P的值呢?

因为这样以后在判断每个state【i】能否满足地形条件时最方便~

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;

int row[110];
int dp[110][110][110];
int n, m;
int nstate;
int state[100];
int num[15];

bool line_ok(int x) {
if ((x & (x << 1))) return false;
if (x & (x << 2)) return false;

return true;
}

void init() {
nstate = 0;
for (int i = 0; i < (1 << m); i++) {
if (line_ok(i)) state[nstate++] = i;
}
}

int find_one(int x) {
int cnt = 0;
//计算二进制中1的位数
while (x) {
x &= (x - 1);
cnt++;
}
return cnt;
}

int main(void) {
int x;
char map[110][13];
scanf("%d%d", &n, &m);
init();
memset(dp, -1, sizeof(-1));

for (int i = 0; i < n; i++) {
scanf("%s", map[i]);
for (int j = 0; j < m; j++) {
x = 0;
if (map[i][j] == 'H') x = 1;

row[i] += x << j;
}
}
for (int i = 0; i < nstate; i++) {
num[i] = find_one(state[i]);
if (row[0] & state[i]) continue;
dp[0][0][i] = num[i];
}

for (int i = 1; i < n; i++) {
for (int j = 0; j < nstate; j++) //第i行
{
if (row[i] & state[j]) continue;

for (int k = 0; k < nstate; k++) //第i-1行
{
if (row[i - 1] & state[k]) continue;
if (state[j] & state[k]) continue;
for (int t = 0; t < nstate; t++) //第i-2行
{
if (state[t] & state[j]) continue;

if (dp[i - 1][t][k] == -1) continue;

dp[i][k][j] = max(dp[i][k][j], dp[i - 1][t][k] + num[j]);
}
}
}
}

int ans = 0;
for (int i = 0; i < nstate; i++) {
for (int j = 0; j < nstate; j++) ans = max(ans, dp[n - 1][j][i]);
}
printf("%d\n", ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: