Bishwock
题目链接:http://codeforces.com/problemset/problem/991/D
数据范围:略。
题解:
一眼题。
首先,每个$L$最多只占用两列,而且行数特别少,我们考虑状态压缩。
即$f_{i, S}$表示前$i$列,第$j$列的状态为$S$时,前$j$最多能放多少个。
随便弄一弄就好了。
代码:
#include <bits/stdc++.h> #define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout) #define N 100010 using namespace std; int f[N][1 << 4], dic[4]; char s[2][N]; int main() { // setIO("a"); scanf("%s%s", s[0] + 1, s[1] + 1); int n = strlen(s[0] + 1); int all = (1 << 4) - 1; for (int i = 0; i < 4; i ++ ) { dic[i] = all - (1 << i); } for (int i = 2; i <= n; i ++ ) { int mdl = 0; if (s[0][i - 1] == 'X') { mdl += 1; } if (s[1][i - 1] == 'X') { mdl += 2; } if (s[0][i] == 'X') { mdl += 4; } if (s[1][i] == 'X') { mdl += 8; } // cout << mdl << endl ; for (int s1 = 0; s1 < (1 << 2); s1 ++ ) { for (int s2 = 0; s2 < (1 << 2); s2 ++ ) { // i -> s1, i - 1 -> s2 int tmp = s2 + (s1 << 2), re = all - tmp; if ((tmp & mdl) == mdl) { f[i][s1] = max(f[i][s1], f[i - 1][s2]); for (int k = 0; k < 4; k ++ ) { if ((dic[k] & re) == dic[k]) { int x = s2; if (dic[k] & 1) { x ++ ; } if (dic[k] & 2) { x += 2; } f[i][s1] = max(f[i][s1], f[i - 1][x] + 1); } } } } } } int ans = 0; for (int i = 0; i <= all; i ++ ) { ans = max(ans, f[n][i]); } cout << ans << endl ; fclose(stdin), fclose(stdout); return 0; }
小结:一定要想明白状态再转移。