您的位置:首页 > 其它

poj 1185 炮兵阵地 //状态压缩DP

2011-08-15 21:24 399 查看
注意只有一行等这些特殊情况

这种状态压缩DP还是比较简单的,这个题是前2行推出下一行的状态

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = (1 << 10);
int n, m;
char s[12];
int state[101][100];
int dp[2][100][100];//循环数组
int num[MAXN];
void init()
{
for(int i = 0; i < MAXN; i++)
{
int temp = i;
num[i] = 0;
while(temp)
{
if(temp & 1) num[i]++;
temp >>= 1;
}
}
}
void get_state(int id, int val)
{
state[id][0] = 0;
for(int i = 0; i <= val; i++)
{
if((i | val) != val) continue;
if((i & (i << 1)) || (i & (i >> 1))) continue;
if((i & (i << 2)) || (i & (i >> 2))) continue;
state[id][++state[id][0]] = i;
}
}
int main()
{
init();
while(scanf("%d%d", &n, &m) != EOF)
{
for(int i = 0; i < n; i++)
{
scanf("%s", s);
int val = 0;
for(int j = 0; j < m; j++)
{
val <<= 1;
if(s[j] == 'P') val += 1;
}
get_state(i, val);
}

int sum = 0;
for(int i = 1; i <= state[0][0]; i++)
{
dp[0][i][0] = num[state[0][i]];
sum = max(sum, dp[0][i][0]);
}

for(int i = 1; i <= state[1][0]; i++)
{
for(int j = 1; j <= state[0][0]; j++)
{
dp[1][i][j] = -1;
if(state[1][i] & state[0][j]) continue;
dp[1][i][j] = dp[0][j][0] + num[state[1][i]];
sum = max(sum, dp[1][i][j]);
}
}

for(int i = 2; i < n; i++)
{
int a = i % 2;
int b = 1 - a;
for(int x = 1; x <= state[i][0]; x++)
{
for(int y = 1; y <= state[i-1][0]; y++)
{
dp[a][x][y] = -1;
if(state[i][x] & state[i-1][y]) continue;
for(int z = 1; z <= state[i-2][0]; z++)
{
if(state[i][x] & state[i-2][z]) continue;
if(state[i-1][y] & state[i-2][z]) continue;
if(dp[b][y][z] == -1) continue;
dp[a][x][y] = max(dp[a][x][y], dp[b][y][z] + num[state[i][x]]);
//if(i == n - 1 && dp[a][x][y] > 0) printf("%d\n",dp[a][x][y]);
}
}
}
}

int a = (n - 1) % 2;
for(int i = 1; i <= state[n-1][0]; i++)
for(int j = 1; j <= state[n-2][0]; j++)
{
if(dp[a][i][j] > sum) sum = dp[a][i][j];
}

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