AOJ - PI
열심히 $O(N)$ DP 를 구현해주면 된다.
void solve() {
string s;
cin >> s;
int n = sz(s);
s = " " + s;
vi dp(n + 1, 1e15);
dp[0] = 0;
auto check2 = [&](string s) -> int {
bool f = 1;
for (int i = 1; i < sz(s); i++) {
if (s[i] != s[i - 1] + 1) f = 0;
}
if (f) return 1;
f = 1;
for (int i = 1; i < sz(s); i++) {
if (s[i] != s[i - 1] - 1) f = 0;
}
return f;
};
for (int i = 3; i <= n; i++) {
{
string sub = s.substr(i - 2, 3);
if (cntt(sub, sub[0]) == 3) {
dp[i] = min(dp[i], dp[i - 3] + 1);
} else if (check2(sub)) {
dp[i] = min(dp[i], dp[i - 3] + 2);
} else if (sub[0] == sub[2]) {
dp[i] = min(dp[i], dp[i - 3] + 4);
} else if (sub[1] - sub[0] == sub[2] - sub[1]) {
dp[i] = min(dp[i], dp[i - 3] + 5);
} else {
dp[i] = min(dp[i], dp[i - 3] + 10);
}
}
if (i >= 4) {
string sub = s.substr(i - 3, 4);
if (cntt(sub, sub[0]) == 4) {
dp[i] = min(dp[i], dp[i - 4] + 1);
} else if (check2(sub)) {
dp[i] = min(dp[i], dp[i - 4] + 2);
} else if (sub[0] == sub[2] && sub[1] == sub[3]) {
dp[i] = min(dp[i], dp[i - 4] + 4);
} else if (sub[1] - sub[0] == sub[2] - sub[1] && sub[2] - sub[1] == sub[3] - sub[2]) {
dp[i] = min(dp[i], dp[i - 4] + 5);
} else {
dp[i] = min(dp[i], dp[i - 4] + 10);
}
}
if (i < 5) continue;
{
string sub = s.substr(i - 4, 5);
if (cntt(sub, sub[0]) == 5) {
dp[i] = min(dp[i], dp[i - 5] + 1);
} else if (check2(sub)) {
dp[i] = min(dp[i], dp[i - 5] + 2);
} else if (sub[0] == sub[2] && sub[0] == sub[4] && sub[1] == sub[3]) {
dp[i] = min(dp[i], dp[i - 5] + 4);
} else if (sub[1] - sub[0] == sub[2] - sub[1] && sub[2] - sub[1] == sub[3] - sub[2]
&& sub[3] - sub[2] == sub[4] - sub[3]) {
dp[i] = min(dp[i], dp[i - 5] + 5);
} else {
dp[i] = min(dp[i], dp[i - 5] + 10);
}
}
}
cout << dp[n] << endl;
}
Comments