POJ 1185(状态压缩DP)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1185(状态压缩DP)相关的知识,希望对你有一定的参考价值。

和POJ 3254很像。连续两个都不一样需要添加移位两位的条件,dp数组中多了一维保存上上一行。递推公式也变成求最大值。

初始化的时候从dp[1][0][i]开始,0是根据st数组的起始。

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

#define Max 1000001
#define MAXN 150000
#define MOD 100000000
#define rin freopen("in.txt","r",stdin)
#define rout freopen("1.out","w",stdout)
#define Del(a,b) memset(a,b,sizeof(a))
#define INF 1000000000
using namespace std;
typedef long long LL;
const int N = 105;
const int M = 70;
int st[M], map[N];
int dp[N][M][M];
int num[M];
char temp[N];
inline bool judge1(int x) {
    if (x & (x << 1))
        return 0;
    if (x & (x << 2))
        return 0;
    return 1;
}
bool judge2(int i, int x) {
    return (map[i] & st[x]);
}
int getnum(int i) {
    int ret = 0;
    while (i) {
        ret++;
        i &= i - 1;
    }
    return ret;
}
int main() {
    //rin;
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF) {
        if (n == 0 && m == 0)
            break;
        Del(st, 0);
        Del(map, 0);
        Del(dp, -1);
        Del(num, 0);
        for (int i = 1; i <= n; i++) {
            scanf("%s", temp + 1);
            for (int j = 1; j <= m; j++) {
                if (temp[j] == H)
                    map[i] += (1 << (j - 1));
            }
        }
        int cnt = 0;
        for (int i = 0; i < (1 << m); i++) {
            if (judge1(i)) {
                st[cnt] = i;
                cnt++;
            }
        }

        for (int i = 0; i < cnt; i++) {
            num[i] = getnum(st[i]);
            if (!judge2(1, i))
                dp[1][0][i] = num[i];
        }
        for (int i = 2; i <= n; i++) {
            for (int t = 0; t < cnt; t++) {
                if (judge2(i, t))
                    continue;
                for (int j = 0; j < cnt; j++) {
                    if (st[t] & st[j])
                        continue;
                    for (int k = 0; k < cnt; k++) {
                        if (st[t] & st[k])
                            continue;
                        if (dp[i - 1][j][k] == -1)
                            continue;
                        dp[i][k][t] = max(dp[i][k][t],
                                dp[i - 1][j][k] + num[t]);
                    }
                }
            }
        }

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

 

以上是关于POJ 1185(状态压缩DP)的主要内容,如果未能解决你的问题,请参考以下文章

POJ1185 炮兵阵地 (状态压缩DP)

POJ1185炮兵阵地(状态压缩DP)

POJ1185炮兵阵地(插头DP+状态压缩)

poj1185 状态压缩经典题

poj1185 [NOI2001]炮兵阵地

poj 1185 炮兵阵地(状压DP)