[CF991D]Bishwock_状压dp
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;
}
小结:一定要想明白状态再转移。
| 欢迎来原网站坐坐! >原文链接<

浙公网安备 33010602011771号