// Compile with: g++ -std=c++20 -O2 -pipe -march=native -o knap knap.cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int S; int N;
if (!(cin >> S >> N)) return 0;
struct Item { int w; ll v; };
vector<Item> items;
items.reserve(N * 4); // heuristic
for (int i = 0; i < N; ++i) {
ll V; int W; long long K;
cin >> V >> W >> K;
if (W > S) {
// if single item's weight > capacity, none of its copies fit
continue;
}
// Cap maximum usable copies by capacity: at most S / W copies can ever be taken
long long usable = min(K, (long long)(S / W));
long long take = 1;
while (usable > 0) {
long long cur = min(take, usable);
int newW = int(cur * W);
ll newV = V * cur;
// newW <= S by construction because cur <= usable <= S/W
items.push_back({ newW, newV });
usable -= cur;
take <<= 1;
}
}
// 0/1 knapsack on constructed items
vector<ll> dp(S + 1, 0);
for (const auto &it : items) {
int w = it.w;
ll v = it.v;
for (int cap = S; cap >= w; --cap) {
ll cand = dp[cap - w] + v;
if (cand > dp[cap]) dp[cap] = cand;
}
}
// answer is max value for capacity <= S (dp[S] already holds max for S)
cout << dp[S] << '\n';
return 0;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |