제출 #1082312

#제출 시각아이디문제언어결과실행 시간메모리
1082312vuavisaoKnapsack (NOI18_knapsack)C++14
100 / 100
177 ms248452 KiB
#include <bits/stdc++.h> #pragma GCC optimize("O3", "unroll-loops") using namespace std; using ll = long long; const int N = 100'000 + 10; const int WEIGHT = 2'000 + 10; int n, maxWeight; int values[N], weight[N], cnt[N]; namespace sub3 { bool check() { return (n <= 100 && *max_element(cnt + 1, cnt + 1 + n) <= 10); } void solve() { vector<vector<ll>> dp(n + 10, vector<ll>(maxWeight + 10, 0)); for (int i = 0; i < n; ++ i) { for (int s = 0; s <= maxWeight; ++ s) { int cost = values[i + 1], w = weight[i + 1]; ll curCost = 0, curW = 0; for (int j = 0; j <= cnt[i + 1]; ++ j) { if (curW + s > maxWeight) break; dp[i + 1][s + curW] = max(dp[i + 1][s + curW], dp[i][s] + curCost); curCost += cost; curW += w; } } } cout << *max_element(dp[n].begin(), dp[n].end()); } } namespace sub4 { bool check() { return (n <= 100); } vector<pair<ll, ll>> bag; void splitItem(int cost, int w, int cnt) { for (ll pw = 1; cnt >= pw; pw *= 2ll) { bag.push_back(make_pair(1ll * cost * pw, 1ll * w * pw)); cnt -= pw; } if (cnt > 0) { bag.push_back(make_pair(1ll * cost * cnt, 1ll * w * cnt)); } } void solve() { bag.push_back(make_pair(0, 0)); for (int i = 1; i <= n; ++ i) splitItem(values[i], weight[i], cnt[i]); n = (int) bag.size() - 1; vector<vector<ll>> dp(n + 10, vector<ll>(maxWeight + 10, 0)); for (int i = 0; i < n; ++ i) { ll cost = bag[i + 1].first, w = bag[i + 1].second; for (int s = 0; s <= maxWeight; ++ s) { dp[i + 1][s] = max(dp[i + 1][s], dp[i][s]); if (w + s <= maxWeight) { dp[i + 1][s + w] = max(dp[i + 1][s + w], dp[i][s] + cost); } } } cout << *max_element(dp[n].begin(), dp[n].end()); } } namespace sub5 { vector<int> position; vector<pair<int, int>> bag; void makeGroup(int l, int r) { int w = weight[position[l]]; int maxCnt = maxWeight / w; for (int i = l; maxCnt > 0 && i <= r; ++ i) { int idx = position[i]; int cost = values[idx]; while (maxCnt > 0 && cnt[idx] > 0) { -- maxCnt; -- cnt[idx]; bag.push_back(make_pair(cost, w)); } } } void solve() { for (int i = 1; i <= n; ++ i) position.push_back(i); sort(position.begin(), position.end(), [&] (int lhs, int rhs) -> bool { if (weight[lhs] != weight[rhs]) return weight[lhs] < weight[rhs]; return values[lhs] > values[rhs]; }); bag.push_back(make_pair(0, 0)); for (int l = 0, r = 0; l < n; l = r) { while (r < n && weight[position[l]] == weight[position[r]]) ++ r; makeGroup(l, r - 1); } n = (int) bag.size() - 1; vector<vector<ll>> dp(n + 10, vector<ll>(maxWeight + 10, 0)); for (int i = 0; i < n; ++ i) { ll cost = bag[i + 1].first, w = bag[i + 1].second; for (int s = 0; s <= maxWeight; ++ s) { dp[i + 1][s] = max(dp[i + 1][s], dp[i][s]); if (w + s <= maxWeight) { dp[i + 1][s + w] = max(dp[i + 1][s + w], dp[i][s] + cost); } } } cout << *max_element(dp[n].begin(), dp[n].end()); } } int32_t main() { std::ios_base::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); cin >> maxWeight >> n; for (int i = 1; i <= n; ++ i) cin >> values[i] >> weight[i] >> cnt[i]; if (sub3::check()) { sub3::solve(); return 0; } if (sub4::check()) { sub4::solve(); return 0; } sub5::solve(); return (0 ^ 0); } /// Code by vuavisao
#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...