Submission #1194024

#TimeUsernameProblemLanguageResultExecution timeMemory
1194024dungttKnapsack (NOI18_knapsack)C++20
0 / 100
0 ms324 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; int main() { ios::sync_with_stdio(false); cin.tie(NULL); int N; // Số loại vật liệu ll W; // Sức chứa của balo (trọng lượng tối đa) cin >> N >> W; // Mảng dp[j] lưu giá trị tối đa khi cân nặng chính xác là j vector<ll> dp(W+1, 0); // Duyệt qua từng loại vật liệu for(int i = 0; i < N; i++) { ll w, v, k; cin >> k >> w >> v; // Đọc số lượng k, trọng số w, giá trị v của loại vật i // Nếu một vật chiếm trọng lượng 0 và có giá trị dương, ta có thể lặp vô hạn. // Tuy nhiên, nếu w = 0 nhưng v <= 0 hoặc dp không đổi, ta bỏ qua luôn. if (w == 0) continue; // Nếu K rất lớn: đủ để lấp đầy mọi trọng số, coi như knapsack không giới hạn if (k * w >= W) { // Cập nhật như bài toán unbounded knapsack (lấy không giới hạn) // Duyệt từ trọng lượng w đến W (tăng dần) để không dùng một vật nhiều lần trong cùng một lần lặp for (ll j = w; j <= W; j++) { dp[j] = max(dp[j], dp[j - w] + v); } continue; } // Trường hợp bounded knapsack với k nhỏ: dùng sliding window // Tạo bản sao dp cũ để tham chiếu (những giá trị trước khi thêm loại vật này) vector<ll> dp_old = dp; // Duyệt các phần dư r = 0..w-1 for(int r = 0; r < w; r++) { // Sử dụng deque để lưu các cặp (t_index, H_value) deque<pair<ll,ll>> dq; // t là số đơn vị w đang xét, tương ứng vị trí j = r + t*w ll max_t = (W - r) / w; for(ll t = 0; t <= max_t; t++) { ll j = r + t * w; ll H = dp_old[j] - t * v; // giá trị H(t) = dp_old[r+t*w] - t*v // Loại bỏ chỉ số đã ra khỏi phạm vi cửa sổ (t - k) while (!dq.empty() && dq.front().first < t - k) { dq.pop_front(); } // Đưa chỉ số mới t vào deque, giữ thứ tự H giảm dần while (!dq.empty() && dq.back().second <= H) { dq.pop_back(); } dq.emplace_back(t, H); // Cập nhật dp[r + t*w] = dp_new[r+t*w] // Công thức: t*v + max(H(u) trong cửa sổ) = deque.front().second + t*v ll best = dq.front().second + t * v; dp[j] = max(dp[j], best); } } } // Kết quả: giá trị lớn nhất trong dp[0..W] ll ans = 0; for(ll j = 0; j <= W; j++) { ans = max(ans, dp[j]); } cout << ans; 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...