题解:CF1366G Construct the String
唐氏 DP 题。
原题相当于选择一个
设
其中 . 弹出栈顶,如果遇到 . 且栈为空就把答案加
考虑优化,你肯定考虑按
你考虑扫描线,对于所有
分讨一下
发现上述操作体现在
这个东西可以简单线性维护,所以总复杂度
#include<bits/stdc++.h>
#include<bits/extc++.h>
using ll = long long; using ull = unsigned long long;
#define ld std::cin
#define jyt std::cout
#define cmd std::cerr
#define REQ(i, l, r) for (int i = l; i < r; ++i)
#define REP(i, l, r) for (int i = l; i <= r; ++i)
#define PER(i, l, r) for (int i = l; i >= r; --i)
namespace JoKing { // JoKing 12:15 10pts
const int N = 1e4 + 7;
const int inf = 0x3f3f3f3f;
int n, m, f[2][N], g[N << 1], sg[N << 1], DLT = 10002, TAG = 0;
inline int& MAGA(int x) {return g[x + DLT];}
inline int& MAMA(int x) {return sg[x + DLT];}
std::string S, T;
signed main() {
ld >> S >> T, n = (int)S.length(), m = (int)T.length(), S = "#" + S, T = "#" + T;
memset(f[0], 0x3f, sizeof(f[0])), f[0][0] = 0;
REQ(TOT, 0, m) {
int now = (TOT & 1), nxt = (now ^ 1);
memset(f[nxt], 0x3f, sizeof(f[nxt]));
memset(g, 0x3f, sizeof(g)), memset(sg, 0x3f, sizeof(sg)), DLT = 10002, TAG = 0;
REP(i, TOT, n) {
if (S[i] == T[TOT + 1]) f[nxt][i] = MAMA(0) + TAG;
if (S[i] == '.') {
--TAG;
MAGA(1) = std::min(MAGA(1), MAGA(0) + 2);
MAMA(1) = std::min(MAMA(1), MAGA(0) + 2);
MAGA(0) = MAMA(0) = inf;
++DLT;
} else {
--DLT, ++TAG;
MAGA(0) = inf;
MAMA(0) = MAMA(1);
}
if (f[now][i] <= n) {
MAGA(0) = std::min(MAGA(0), f[now][i] - TAG);
MAMA(0) = std::min(MAMA(0), f[now][i] - TAG);
}
}
}
memset(g, 0x3f, sizeof(g)), memset(sg, 0x3f, sizeof(sg)), DLT = 10002, TAG = 0;
REP(i, m, n) {
if (S[i] == '.') {
--TAG;
MAGA(1) = std::min(MAGA(1), MAGA(0) + 2);
MAMA(1) = std::min(MAMA(1), MAGA(0) + 2);
MAGA(0) = MAMA(0) = inf;
++DLT;
} else {
--DLT, ++TAG;
MAGA(0) = inf;
MAMA(0) = MAMA(1);
}
if (f[m & 1][i] <= n) {
MAGA(0) = std::min(MAGA(0), f[m & 1][i] - TAG);
MAMA(0) = std::min(MAMA(0), f[m & 1][i] - TAG);
}
}
jyt << MAMA(0) + TAG << '\n';
return 0;
}
}
signed main() {
#ifdef WYY
freopen("cmd.in", "r", stdin);
freopen("cmd.out", "w", stdout);
double S_TIME = clock();
cmd << "[start running]\n";
#else
// freopen("construct.in", "r", stdin);
// freopen("construct.out", "w", stdout);
#endif
std::ios::sync_with_stdio(false), ld.tie(0), jyt.tie(0);
JoKing::main();
#ifdef WYY
double E_TIME = clock();
cmd << "[finished in " << E_TIME - S_TIME << "ms]\n";
// while(true);
#endif
return 0;
}