Lesson 25 — Knapsack Family

Họ bài toán cái balo: một bộ khung DP, nhiều biến thể. Khám phá bảng dp[i][w], vì sao hướng duyệt w quyết định 0/1 hay unbounded, và coin change min vs đếm cách.

1. Bảng 0/1 Knapsack + truy vết món

Mỗi món lấy 0 hoặc 1 lần. Điền bảng dp[i][w] từng ô, highlight ô nguồn (lấy / không lấy), rồi truy vết tập món được chọn.

dp[i][w] = max( dp[i-1][w] /*không lấy*/ , dp[i-1][w-wt[i]] + val[i] /*lấy*/ )
Nhấn "Điền bảng" để bắt đầu.
ô đang tính ô nguồn (lấy/không) đường truy vết

2. Hướng duyệt w: 0/1 (ngược) vs Unbounded (xuôi)

Cùng một món, cùng mảng dp[w] 1 chiều. Chỉ khác hướng duyệt: 0/1 đi ngược (W→wt) nên mỗi món lấy ≤ 1 lần; unbounded đi xuôi (wt→W) nên lấy lại được nhiều lần.

0/1 — duyệt NGƯỢC (w: W → wt)

dp[w-wt] còn là giá trị CŨ → mỗi món 1 lần.

Unbounded — duyệt XUÔI (w: wt → W)

dp[w-wt] đã MỚI → lấy lại món nhiều lần.
Nhấn "Chạy song song" để xem khác biệt.

3. Coin Change — min đồng & đếm số cách

Cùng coinsamount: min dùng dp[a]=min(dp[a], dp[a-c]+1); đếm cách dùng dp[a]+=dp[a-c] (coin vòng ngoài → đếm tổ hợp).

Chọn "Min coins" hoặc "Đếm số cách".