Submission #1276475

#TimeUsernameProblemLanguageResultExecution timeMemory
1276475mehrzadFestival (IOI25_festival)C++17
0 / 100
1084 ms2162688 KiB
#include <bits/stdc++.h> using namespace std; struct Coupon { int idx; // original index long long P; // price int T; // multiplier }; static long long ceilDiv(long long a, int b) { // a >= 0 , b >= 1 return (a + b - 1) / b; } // --------------------------------------------------------------- // max_coupons : required function // --------------------------------------------------------------- vector<int> max_coupons(int A, vector<int> P, vector<int> T) { int N = (int)P.size(); vector<Coupon> all(N); for (int i = 0; i < N; ++i) { all[i] = {i, (long long)P[i], T[i]}; } /* ---------- sort by increasing R = P*T/(T-1) ---------- T = 1 → R = +∞ (they are placed after all T>1) */ auto cmp = [](const Coupon& a, const Coupon& b) -> bool { bool a_one = (a.T == 1); bool b_one = (b.T == 1); if (a_one && b_one) return a.idx < b.idx; // any stable order if (a_one) return false; // a after b if (b_one) return true; // a before b __int128 left = (__int128)a.P * a.T * (b.T - 1); __int128 right = (__int128)b.P * b.T * (a.T - 1); if (left != right) return left < right; if (a.P != b.P) return a.P < b.P; // tie‑break return a.idx < b.idx; }; sort(all.begin(), all.end(), cmp); /* ---------- DP over the list, processed from large R to small R ---------- reverse order → we always add the current coupon at the front */ vector<Coupon> order = all; reverse(order.begin(), order.end()); const long long INF = (1LL << 60); vector<vector<long long>> dp(N + 1, vector<long long>(N + 1, INF)); vector<vector<char>> take(N + 1, vector<char>(N + 1, 0)); dp[0][0] = 0; // empty set for (int i = 0; i < N; ++i) { // initialise row i+1 for (int k = 0; k <= i + 1; ++k) { dp[i + 1][k] = INF; take[i + 1][k] = 0; } // skip the i‑th coupon for (int k = 0; k <= i; ++k) { if (dp[i][k] < dp[i + 1][k]) { dp[i + 1][k] = dp[i][k]; take[i + 1][k] = 0; } } // take the i‑th coupon (it becomes the first one) const Coupon& c = order[i]; for (int k = 0; k <= i; ++k) { if (dp[i][k] == INF) continue; long long cand = c.P + ceilDiv(dp[i][k], c.T); if (cand < dp[i + 1][k + 1]) { dp[i + 1][k + 1] = cand; take[i + 1][k + 1] = 1; } } } // largest feasible number of coupons int bestK = 0; for (int k = N; k >= 0; --k) { if (dp[N][k] <= (long long)A) { bestK = k; break; } } // reconstruct the purchase order (forward order) vector<int> answer; int i = N, k = bestK; while (i > 0) { if (k > 0 && take[i][k]) { answer.push_back(order[i - 1].idx); // original index --k; --i; } else { --i; // coupon was skipped } } // the `answer` vector already contains the coupons in the order they // have to be bought. 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...