제출 #1121732

#제출 시각아이디문제언어결과실행 시간메모리
1121732vjudge1Boarding Passes (BOI22_passes)C++17
100 / 100
206 ms215372 KiB
#include <bits/stdc++.h>
#define f first
#define s second
#define ent '\n'
#define int long long

typedef long long ll;
using namespace std;
const int maxn = 1e5 + 12;
const int mod = 1e9 + 7;

vector<int> g[30];
int cnt[16][16][maxn];
int dp[1 << 16];
int pref[30][maxn];
int suff[30][maxn];
int a[maxn];
int n, m, k;

int get(int x, int pos, int mask) {
    int sz = (int)g[x].size();
    int ans = pos * (pos - 1) / 2 + (sz - pos) * (sz - pos - 1) / 2;
    for(int y = 0; y < m; y++) {
        if(x == y || ((mask >> y) & 1) == 0) continue;
        ans += cnt[x][y][pos] * 2;
    }
    return ans;
}

void solve() {
    m = 15;
    string s;
    cin >> s;
    n = (int)s.size();
    s = '+' + s;
    for(int i = 1; i <= n; i++) {
        a[i] = s[i] - 'A';
        g[a[i]].push_back(i);
    }
    for(int x = 0; x < 15; x++) {
        for(int y = 0; y < 15; y++) {
            if(x == y) continue;
            for(int i = 0; i <= (int)g[x].size() + 10; i++) {
                pref[x][i] = suff[x][i] = 0;
            }
            for(int i = 0, j = 0; i < g[x].size(); i++) {
                int val = g[x][i];
                while(j < g[y].size() && g[y][j] <= val) {
                    j++;
                }
                pref[x][i + 1] = pref[x][i] + j;
            }
            for(int i = (int)g[x].size() - 1, j = (int)g[y].size() - 1; i >= 0; i--) {
                int val = g[x][i];
                while(j >= 0 && g[y][j] >= val) {
                    j--;
                }
                suff[x][i + 1] = suff[x][i + 2] + (int)g[y].size() - j - 1;
            }
            for(int i = 0; i <= (int)g[x].size(); i++) {
                cnt[x][y][i] = pref[x][i] + suff[x][i + 1];
            }
        }
    }
    for(int mask = 1; mask < (1 << m); mask++) {
        dp[mask] = 1e18;
        for(int x = 0; x < m; x++) {
            if(((mask >> x) & 1) == 0) {
                continue;
            }
            int tm = (mask ^ (1 << x));
            dp[mask] = min(dp[mask], get(x, 0, mask) + dp[tm]);
            for(int l = 1, r = (int)g[x].size(); l <= r;) {
                int mid = l + r >> 1;
                int tx = get(x, mid - 1, mask), ty = get(x, mid, mask);
                dp[mask] = min({dp[mask], tx + dp[tm], ty + dp[tm]});
                if(tx > ty) {
                    l = mid + 1;
                }
                else {
                    r = mid - 1;
                }
            }
        }
    }
    cout << setprecision(9) << fixed << (double)dp[(1 << m) - 1] / 2.0 << ent;
}

signed main(){

    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1;

//    cin >> t;
    while(t--){
        solve();
    }
}

컴파일 시 표준 에러 (stderr) 메시지

passes.cpp: In function 'void solve()':
passes.cpp:46:37: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   46 |             for(int i = 0, j = 0; i < g[x].size(); i++) {
      |                                   ~~^~~~~~~~~~~~~
passes.cpp:48:25: warning: comparison of integer expressions of different signedness: 'long long int' and 'std::vector<long long int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   48 |                 while(j < g[y].size() && g[y][j] <= val) {
      |                       ~~^~~~~~~~~~~~~
passes.cpp:74:29: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   74 |                 int mid = l + r >> 1;
      |                           ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...