제출 #1237362

#제출 시각아이디문제언어결과실행 시간메모리
1237362Double_SlashBoarding Passes (BOI22_passes)C++20
100 / 100
487 ms64440 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; #define all(x) x.begin(), x.end() int main() { string s; cin >> s; int n = s.size(), g = *max_element(all(s)) - 'A' + 1; ll ev[g][1 << g]{}; auto c = [&] (int x) { return (ll) x * (x - 1) / 2; }; for (int j = g; j--;) { vector<int> v; for (int i = 0; i < n; ++i) { if (s[i] - 'A' == j) v.emplace_back(i); } if (v.empty()) continue; struct : vector<int> { vector<ll> ps{0}, iw{0}; void init() { for (int i = 0; i < size(); ++i) { ps.emplace_back(ps.back() + (*this)[i]); iw.emplace_back(iw.back() + (i + 1) * (*this)[i]); } } ll operator()(int l, int r) { return iw[r + 1] - iw[l] - l * (ps[r + 1] - ps[l]); } } l[g], r[g]; for (int k = g; k--;) { l[k].resize(v.size() + 1); r[k].resize(v.size() + 1); } for (int i = n, idx = -1; i--;) { if (~idx) l[s[i] - 'A'][idx] += 1 + (s[i] - 'A' != j); if (s[i] - 'A' == j) ++idx; } for (int i = 0, idx = -1; i < n; ++i) { if (~idx) r[s[i] - 'A'][idx] += 1 + (s[i] - 'A' != j); if (s[i] - 'A' == j) ++idx; } for (int k = g; k--;) { l[k].init(); r[k].init(); } auto gl = [&] (int i, int m) { ll cur = 0; m |= 1 << j; for (int k = g; k--;) cur += ((m >> k) & 1) * l[k](v.size() - i, v.size() - 1); return cur; }; auto gr = [&] (int i, int m) { ll cur = 0; m |= 1 << j; for (int k = g; k--;) cur += ((m >> k) & 1) * r[k](i, v.size() - 1); return cur; }; for (int m = 1 << g; m--;) { if ((m >> j) & 1) continue; ev[j][m] = min(gr(0, m), gl(v.size(), m)); if (v.size() == 1) continue; int i = 1; for (int k = 17; k--;) { if (i + (1 << k) + 1 >= v.size()) continue; i += 1 << k; if (gl(i + 1, m) + gr(i + 1, m) >= gl(i, m) + gr(i, m)) i -= 1 << k; } ev[j][m] = min(ev[j][m], gl(i, m) + gr(i, m)); if (i + 1 < v.size()) ev[j][m] = min(ev[j][m], gl(i + 1, m) + gr(i + 1, m)); } } ll dp[1 << g]; memset(dp, 0x3f, sizeof dp); dp[0] = 0; for (int m = 0; m < (1 << g); ++m) { for (int i = g; i--;) { if ((m >> i) & 1) continue; dp[m | (1 << i)] = min(dp[m | (1 << i)], dp[m] + ev[i][m]); } } cout << dp[(1 << g) - 1] / 2; if (dp[(1 << g) - 1] & 1) cout << ".5"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...