Submission #601376

#TimeUsernameProblemLanguageResultExecution timeMemory
601376GusterGoose27Vim (BOI13_vim)C++11
48.06 / 100
298 ms150888 KiB
#include <bits/stdc++.h> using namespace std; const int MAXN = 70000; const int inf = 1e9; int n; int dp[MAXN][1 << 9]; // dont return to i int dq[MAXN]; // return to i int elems[MAXN]; int nextocc[MAXN][10]; bool ise[MAXN]; int nextdp[9]; int avail[MAXN+1]; class stree { public: stree *l = nullptr; stree *r = nullptr; int lp, rp; int mne; int cont_mask = 0; stree(int lv, int rv) { lp = lv; rp = rv; if (lp == rp) { if (ise[lp]) mne = lp; else mne = n; if (elems[lp] < 9) cont_mask = (1 << elems[lp]); } else { int m = (lp+rp)/2; l = new stree(lp, m); r = new stree(m+1, rp); mne = min(l->mne, r->mne); cont_mask = l->cont_mask | r->cont_mask; } } int query(int lv, int rv) { if (lp > rv || rp < lv) return n; if (lp >= lv && rp <= rv) return mne; return min(l->query(lv, rv), r->query(lv, rv)); } int get_cont(int lv, int rv) { if (lp > rv || rp < lv) return 0; if (lp >= lv && rp <= rv) return cont_mask; return l->get_cont(lv, rv) | r->get_cont(lv, rv); } }; void make_dp(int i, int pos = 0, int mask = 0, int best = inf) { if (pos == 9) { int other = inf; if ((mask < ((1<<9)-1))) other = 2+dp[i][(1<<9)-1]; dp[i][mask] = min(other, best); return; } make_dp(i, pos+1, mask+(1<<pos), min(best, nextdp[pos])); make_dp(i, pos+1, mask, best); } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cin >> n; string s; cin >> s; int nume = 0; for (int i = 0; i < n; i++) { int v = s[i]-'a'; if (v == 4) { ise[i] = 1; v = 10; } if (v > 4) v--; elems[i] = v; nume += ise[i]; } int seen[10]; for (int i = 0; i < 10; i++) seen[i] = n; avail[n] = n; for (int i = n-1; i >= 0; i--) { for (int j = 0; j < 10; j++) nextocc[i][j] = seen[j]; seen[elems[i]] = i; avail[i] = avail[i+1]; if (elems[i] < 9) avail[i] = i; } stree *tree = new stree(0, n-1); for (int i = n-1; i >= 0; i--) { if (elems[i] == 9) continue; if (nextocc[i][9] == n) { for (int mask = 0; mask < (1<<9); mask++) { dp[i][mask] = 0; } dq[i] = 0; continue; } dq[i] = inf; for (int j = 0; j < 9; j++) { int nextpos = nextocc[i][j]; if (nextpos == n) { nextdp[j] = inf; continue; } dq[i] = min(dq[i], dq[nextpos]+nextpos-i+2); int le = tree->query(i, nextpos); if (le == n) { nextdp[j] = 2+dp[nextpos][(1 << 9)-1]; continue; } nextdp[j] = 2+nextpos-le; if (nextocc[nextpos][9] == n) continue; int allow = ((1 << 9)-1)^(tree->get_cont(avail[le]+1, nextpos)); nextdp[j] += min(dq[nextpos], dp[nextpos][allow]); } make_dp(i); } cout << (nume+dp[0][(1 << 9)-1]) << "\n"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...