和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); } }
时间: 2024-10-12 04:11:23