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

来源:互联网 发布:知乎filco红轴 编辑:程序博客网 时间:2024/05/20 08:44

题目链接:POJ 1185 炮兵阵地

状压DP第二题。。摸索中。。今天喝多了,就写了一题,堕落了。。明天奋起~

状态转移方程:dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][l] + sum[j]);,dp[i][j][k] 表示第i行的状态为j,第i - 1行的状态为k时前i行最大放置炮兵数。

#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int MAX_N = 100 + 10;const int MAX_M = 70;int _map[MAX_N], dp[MAX_N][MAX_M][MAX_M], state[MAX_M], sum[MAX_M];int n, m, cnt;bool is_ok(int s){    if(s & (s << 1))       return false;    if(s & (s << 2))        return false;    return true;}int getSum(int s){    int ans = 0;    while(s > 0)    {        if(s & 1)            ans++;        s >>= 1;    }    return ans;}void getState(){    int len = (1 << m);    for(int i = 0; i < len; i++)    {        if(is_ok(i))        {            state[cnt] = i;            sum[cnt] = getSum(i);            cnt++;        }    }}int main(){    //freopen("in.txt", "r", stdin);    memset(dp, -1, sizeof(dp));    cnt = 0;    memset(_map, 0, sizeof(_map));    scanf("%d%d", &n, &m);    char str[12];    for(int i = 0; i < n; i++)    {        scanf("%s", str);        for(int j = 0; j < m; j++)        {            if(str[j] == 'H')                _map[i] |= (1 << j);        }    }    getState();    for(int i = 0; i < cnt; i ++)        if(!(state[i] & _map[0]))            dp[0][i][0] = sum[i];    for(int i = 1; i < n; i++)    {        for(int j = 0; j < cnt; j++)        {            if(!(_map[i] & state[j]))            {                for(int k = 0; k < cnt; k++)                {                    if(!(state[j] & state[k]))                    {                        for(int l = 0; l < cnt; l++)                        {                            if(!(state[j] & state[l]))                            {                                if(dp[i - 1][k][l] == -1)                                    continue;                                dp[i][j][k] = max(dp[i][j][k], dp[i - 1][k][l] + sum[j]);                            }                        }                    }                }            }        }    }    int res = 0;    for(int i = 0; i < cnt; i++)        for(int j = 0; j < cnt; j++)            res = max(dp[n - 1][i][j], res);    printf("%d\n", res);    return 0;}


0 0