제출 #599710

#제출 시각아이디문제언어결과실행 시간메모리
599710MounirBoarding Passes (BOI22_passes)C++14
0 / 100
9 ms468 KiB
#include <bits/stdc++.h> #define all(v) v.begin(), v.end() #define chmax(x, v) x = max(x, v) #define chmin(x, v) x = min(x, v) #define pb push_back #define pii pair<int, int> #define sz(x) (int)x.size() #define x first #define y second #define int long long using namespace std; const int N = 1e5 + 5, G = 10, B = (1 << G); const int OO = 1e18; int nAvant[N][G], nApres[N][G]; vector<int> occs[G]; int dp[B]; int nInversions(int n){ return (n * n - n); } signed main(){ string line = ""; cin >> line; int nVals = line.length(); vector<int> vals; for (int i = 0; i < nVals; ++i) vals.pb(line[i] - 'A'); for (int c = 0; c < G; ++c) nAvant[0][c] = 0; nAvant[0][vals[0]]++; for (int iVal = 1; iVal < nVals; ++iVal){ for (int val = 0; val < G; ++val) nAvant[iVal][val] = nAvant[iVal - 1][val]; nAvant[iVal][vals[iVal]]++; } for (int iVal = 0; iVal < nVals; ++iVal) for (int val = 0; val < G; ++val) nApres[iVal][val] = nAvant[nVals - 1][val] - nAvant[iVal][val]; for (int iVal = 0; iVal < nVals; ++iVal) occs[vals[iVal]].pb(iVal); for (int mask = 0; mask < B; ++mask) dp[mask] = OO; dp[0] = 0; for (int mask = 0; mask < B; ++mask){ vector<int> presents; for (int i = 0; i < G; ++i){ if ((mask&(1 << i)) > 0) presents.pb(i); } // cout << dp[mask] << endl; for (int c = 0; c < G; ++c){ if ((mask&(1 << c)) == 0){ int nCur = sz(occs[c]); if (nCur == 0){ chmin(dp[mask|(1 << c)], dp[mask]); continue; } vector<int> before, after; for (int iVal : occs[c]){ int sum = 0; for (int present : presents) sum += nAvant[iVal][present]; before.pb(sum); sum = 0; for (int present : presents) sum += nApres[iVal][present]; after.pb(sum); } vector<int> prefix(nCur, 0), suffix(nCur, 0); prefix[0] = before[0]; for (int i = 1; i < nCur; ++i) prefix[i] = prefix[i - 1] + before[i]; suffix[nCur - 1] = after[nCur - 1]; for (int i = nCur - 2; i >= 0; --i) suffix[i] = suffix[i + 1] + after[i]; int best = OO; for (int coupe = -1; coupe < nCur; ++coupe){ int actu = 0; if (coupe >= 0) actu += 4 * prefix[coupe]; if (coupe + 1 < nCur) actu += 4 * suffix[coupe + 1]; actu += nInversions(coupe + 1); actu += nInversions(nCur - coupe - 1); chmin(best, actu); } if (false && mask == 4){ cout << "trans " << c << " " << best << endl; for (int iVal : occs[c]) cout << iVal << " "; cout << endl; for (int i : before) cout << i << " "; cout << endl; for (int i : after) cout << i << " "; cout << endl; cout << "---" << endl; } chmin(dp[mask|(1 << c)], dp[mask] + best); } } } cout << fixed << setprecision(10) << dp[B - 1]/4.0 << endl; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...