제출 #1319485

#제출 시각아이디문제언어결과실행 시간메모리
1319485f0rswornKnapsack (NOI18_knapsack)C++20
73 / 100
1095 ms2000 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); const ll NEG_INF = -(1LL << 60); int S, N; if (!(cin >> S >> N)) return 0; struct Item { int v, w; long long k; }; vector<Item> items; items.reserve(N); for (int i = 0; i < N; ++i) { int v, w; long long k; cin >> v >> w >> k; if (w <= S && k > 0) items.push_back({v, w, k}); // else skip: weight too large to ever pick even one copy } // dp[pos] = best value achievable with total weight exactly pos vector<ll> dp(S + 1, NEG_INF); dp[0] = 0; // Process each item type with monotonic-queue optimization for (const auto &it : items) { int v = it.v; int w = it.w; long long k = it.k; // copy current dp to prev (reads are from prev; writes to dp) auto prev = dp; // process residues modulo w for (int r = 0; r < w; ++r) { // deque stores pairs (j_index, value = prev[pos] - j*v) deque<pair<int, ll>> dq; // iterate over positions pos = r + j * w // j = 0,1,2,... ; pos <= S int maxJ = (S - r) / w; for (int j = 0; j <= maxJ; ++j) { int pos = r + j * w; // candidate value for x = j (to be pushed) // val = prev[pos] - j * v (only meaningful if prev[pos] != NEG_INF) ll cand = NEG_INF; if (prev[pos] != NEG_INF) cand = prev[pos] - (ll)j * v; // push candidate j: maintain deque decreasing by value if (cand != NEG_INF) { while (!dq.empty() && dq.back().second <= cand) dq.pop_back(); dq.emplace_back(j, cand); } // pop front if it's outside window [j - k, j] while (!dq.empty() && dq.front().first < j - k) dq.pop_front(); // front of deque is best x for current j if (!dq.empty()) { ll best = dq.front().second + (ll)j * v; // take max: maybe we don't take any of this item type (prev[pos] // already in dp) dp[pos] = max(dp[pos], best); } // else no valid candidate -> dp[pos] remains as is (can't use this item // type to reach pos) } } } // answer: maximum dp[pos] for pos in [0..S] (weight ≤ S) ll ans = 0; for (int pos = 0; pos <= S; ++pos) if (dp[pos] > ans) ans = dp[pos]; cout << ans << '\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...