Submission #1248161

#TimeUsernameProblemLanguageResultExecution timeMemory
1248161mohamedazizKnapsack (NOI18_knapsack)C++20
100 / 100
50 ms1880 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int S, T; cin >> S >> T; // Read all item types and group by weight: // by_weight[w] = vector of (value, count) for items of weight w map<int, vector<pair<int,int>>> by_weight; for (int t = 0; t < T; t++) { int v, w, cnt; cin >> v >> w >> cnt; if (w <= S && cnt > 0) { by_weight[w].emplace_back(v, cnt); } } // Prepare grouped & truncated lists: // Each entry in `groups` is (weight w, vector of best values) vector<pair<int, vector<int>>> groups; for (auto &kv : by_weight) { int w = kv.first; auto &items = kv.second; // Sort by descending value sort(items.begin(), items.end(), [](auto &a, auto &b){ return a.first > b.first; }); // We only need up to floor(S / w) copies int cap = S / w; vector<int> bestVals; bestVals.reserve(cap); // Take counts from the highest-value items first for (auto &vc : items) { int v = vc.first; int c = vc.second; int take = min(c, cap - (int)bestVals.size()); for (int i = 0; i < take; i++) { bestVals.push_back(v); } if ((int)bestVals.size() == cap) break; } if (!bestVals.empty()) { groups.emplace_back(w, move(bestVals)); } } // DP arrays: dp_prev[s] = best value for weight exactly s using processed groups const ll NEG_INF = LLONG_MIN / 4; vector<ll> dp_prev(S+1, NEG_INF), dp_curr(S+1, NEG_INF); dp_prev[0] = 0; // Process each group for (auto &grp : groups) { int w = grp.first; auto &vals = grp.second; int m = vals.size(); // Build prefix sums of the values: P[k] = sum of first k vals vector<ll> P(m+1, 0); for (int i = 0; i < m; i++) { P[i+1] = P[i] + vals[i]; } // Reset dp_curr fill(dp_curr.begin(), dp_curr.end(), NEG_INF); // For each possible total weight s: for (int s = 0; s <= S; s++) { // Option 1: take 0 items from this group dp_curr[s] = dp_prev[s]; // Option 2: take k items (1 ≤ k ≤ min(m, s/w)) int maxK = min(m, s / w); for (int k = 1; k <= maxK; k++) { ll prev = dp_prev[s - k*w]; if (prev != NEG_INF) { dp_curr[s] = max(dp_curr[s], prev + P[k]); } } } // Move to next group dp_prev.swap(dp_curr); } // The answer is the maximum value for any weight ≤ S ll answer = *max_element(dp_prev.begin(), dp_prev.end()); cout << answer << "\n"; 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...
#Verdict Execution timeMemoryGrader output
Fetching results...