제출 #1276468

#제출 시각아이디문제언어결과실행 시간메모리
1276468mehrzadFestival (IOI25_festival)C++17
12 / 100
1093 ms2162688 KiB
#include <bits/stdc++.h> using namespace std; using int64 = long long; using i128 = __int128_t; struct Mult { int idx; int64 P; int T; }; static bool cmpMult(const Mult& a, const Mult& b) { // Compare a.P * a.T / (a.T-1) < b.P * b.T / (b.T-1) // cross‑multiply: a.P * a.T * (b.T-1) < b.P * b.T * (a.T-1) i128 left = (i128)a.P * a.T * (b.T - 1); i128 right = (i128)b.P * b.T * (a.T - 1); return left < right; } vector<int> max_coupons(int A, vector<int> P, vector<int> T) { int N = (int)P.size(); vector<Mult> mult; vector<int> oneIdx; // indices with T == 1 for (int i = 0; i < N; ++i) { if (T[i] == 1) oneIdx.push_back(i); else mult.push_back({i, (int64)P[i], T[i]}); } // sort multipliers by the metric Pi*Ti/(Ti-1) sort(mult.begin(), mult.end(), cmpMult); int M = (int)mult.size(); const i128 INF = (i128)4'000'000'000'000'000'000LL; // 4·10^18, far larger than any needed value // dp[i][k] = maximal token after considering first i multipliers and taking exactly k of them vector<vector<i128>> dp(M + 1, vector<i128>(M + 1, -1)); vector<vector<char>> take(M + 1, vector<char>(M + 1, 0)); dp[0][0] = (i128)A; for (int i = 1; i <= M; ++i) { const Mult& cur = mult[i - 1]; // not taking this coupon for (int k = 0; k <= i; ++k) { dp[i][k] = dp[i - 1][k]; take[i][k] = 0; } // trying to take it for (int k = 1; k <= i; ++k) { if (dp[i - 1][k - 1] != -1 && dp[i - 1][k - 1] >= (i128)cur.P) { i128 newToken = (dp[i - 1][k - 1] - (i128)cur.P) * (i128)cur.T; if (newToken > INF) newToken = INF; if (newToken > dp[i][k]) { dp[i][k] = newToken; take[i][k] = 1; } else if (newToken == dp[i][k] && !take[i][k]) { // Prefer a path that takes the coupon (helps reconstruction) take[i][k] = 1; } } } } // sort type‑1 coupons by price (to maximise count later) sort(oneIdx.begin(), oneIdx.end(), [&](int a, int b) { return P[a] < P[b]; }); int bestTotal = -1; int bestK = 0; i128 bestToken = -1; // evaluate each possible number of taken multipliers for (int k = 0; k <= M; ++k) { if (dp[M][k] == -1) continue; i128 token = dp[M][k]; i128 cur = token; int tCnt = 0; for (int idx : oneIdx) { if (cur >= (i128)P[idx]) { cur -= (i128)P[idx]; ++tCnt; } else break; } int total = k + tCnt; if (total > bestTotal) { bestTotal = total; bestK = k; bestToken = token; } } // reconstruct the chosen multipliers vector<int> answer; int curK = bestK; for (int i = M; i >= 1; --i) { if (curK > 0 && take[i][curK]) { answer.push_back(mult[i - 1].idx); --curK; } } reverse(answer.begin(), answer.end()); // apply the remaining token to take type‑1 coupons greedily i128 token = bestToken; for (int idx : oneIdx) { if (token >= (i128)P[idx]) { token -= (i128)P[idx]; answer.push_back(idx); } else break; } return answer; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...