Hướng dẫn giải của Atcoder Educational DP Contest D - Knapsack 1
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Tác giả:
Đây là bài toán quy hoạch động cái túi cơ bản. Lưu ý rằng vì ~v_i \le 10^9~, ta không thể lưu ~v_i~ trong mảng ~dp~ của mình. Thay vào đó, có thể lưu khối lượng ~W~ ~(W \le 10^5)~. Gọi ~dp[i][j]~ là tổng giá trị lớn nhất có thể khi xét ~i~ đồ vật đầu tiên và có tổng khối lượng là ~j~. Bài toán trở về quy hoạch động cái túi cơ bản.
Độ phức tạp thuật toán: ~O(N \cdot W)~.
Code mẫu
#include <bits/stdc++.h> using namespace std; const int mx = 1e5+1; template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } long long dp[101][mx]; int w[101], v[101]; int main() { cin.tie(0)->sync_with_stdio(0); int N, W; cin >> N >> W; for(int i = 0; i < N; ++i) cin >> w[i] >> v[i]; for(int i = 0; i < N; ++i) for(int j = 0; j <= W; ++j) { if(j + w[i] <= W) ckmax(dp[i + 1][j + w[i]], dp[i][j] + v[i]); ckmax(dp[i + 1][j], dp[i][j]); } cout << dp[N][W] << endl; }
Bình luận
Ý tưởng: dùng mảng 2 chiều
dp[N+1][W+1]
để lưu memo trạng thái chọn tối đa món thứ i (N), giới hạn trọng lượng j (W), quy hoạch động (lặp).Nếu vật thứ i không được chọn vào phương án tối ưu, thì kết quả tối ưu sẽ được chọn trong (i−1) đồ vật trước đó với giới hạn trọng lượng vẫn là j.
Nếu vật thứ i được chọn vào phương án tối ưu, thì tải trọng còn lại có thể sử dụng là (j−w[i]) cho (i−1) đồ vật phía trước, và ta được thêm giá trị v[i] của vật thứ i. Dĩ nhiên, trường hợp này chỉ xét đến khi j >= w[i].
=>
Kết quả của bài toán chính là
dp[N][W]
. (Cũng có thể chỉ cần mảng 1 chiềudp[W+1]
, nếu nắm được chỉ sốv[i]
vàw[i]
tương ứng 1-index hoặc [i-1] tương ứng 0-index, kết quả làdp[W]
).Knapsack bằng lặp (iterative) thì trực quan hơn đệ quy (recursive), implementation sample như sau:
Bình luận này đã bị ẩn vì có quá nhiều phản ứng tiêu cực. Nhấn để xem.