제출 #590785

#제출 시각아이디문제언어결과실행 시간메모리
590785VanillaRoller Coaster Railroad (IOI16_railroad)C++17
34 / 100
486 ms25424 KiB
#include <bits/stdc++.h>
#include "railroad.h"
typedef long long int64;
using namespace std;
const int maxn = 16;
int64 dp [1 << maxn][maxn];

long long brute (vector <int> s, vector <int> t) {
    int n = s.size();
    for (int i = 0; i < (1 << maxn); i++){
        for (int j = 0; j < maxn; j++){
            dp[i][j] = 1e18;
        }
    }
    for (int i = 0; i < n; i++){
        dp[0][i] = dp[1 << i][i] = 0;
    }
    for (int mask = 0; mask < (1 << n); mask++){
        for (int i = 0; i < n; i++){
            if (mask & (1 << i)) {
                for (int j = 0; j < n; j++){
                    if ((mask & (1 << j)) && i != j) 
                        dp[mask][i] = min(dp[mask][i], dp[mask ^ (1 << i)][j] + max(0ll, (int64) t[j] - s[i]));
                }
            }
        }
    }
    // for (int mask = 0; mask < (1 << n); mask++){
    //     for (int i = 0; i < n; i++){
    //         if (mask & (1 << i)) cout << i << " ";
    //         else cout << 9 << " ";
    //     }
    //     cout << ":";
    //     for (int i = 0; i < n; i++){
    //         cout << setw(4) << dp[mask][i] << " ";
    //     }
    //     cout << "\n";
    // }
    return *min_element(dp[(1 << n) - 1], dp[(1 << n) - 1] + n);
}

long long plan_roller_coaster(vector<int> s, vector<int> t) {
    int n = s.size();
    if (n <= 16) return brute(s, t);
    multiset <pair <int, int> > ms;
    map <pair <int, int>, int> mp;
    pair <int, int> bad = {-1, -1};
    for (int i = 0; i < n; i++) {
        ms.insert({s[i], t[i]});
        mp[{s[i], t[i]}]++;
    }
    for (int i = 0; i < n; i++){
        auto it = ms.lower_bound({t[i], -1});
        if (it == ms.end()){
            bad = {s[i], t[i]};
        }
        else {
            if (*it == make_pair(s[i], t[i]) && mp[{s[i], t[i]}] == 1) it++;
            if (it == ms.end()) {
                bad = {s[i], t[i]};
            }
        }
    }    // if (bad.first != -1) return 1;
    int last = 1;
    for (int i = 0; i < n; i++){
        auto it = ms.lower_bound({last, 0});
        // cout << i << " " << last << " " << it->first << " " << it->second << "\n";
        if (it != ms.end() && *it == bad && i != n-1) it++;
        if (it == ms.end()) return 1;
        last = it->second;
        ms.erase(it);
    }
    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...