Trong phần nói về phương pháp vét cạn, chúng tôi đã đề cập đến bài toán xếp balô nhưng chưa trình bày thuật giải. Dụng ý của chúng tôi là muốn giải bài toán đó bằng phương pháp quy hoạch động. Bạn đọc dễ dàng kiểm chứng được, bài toán xếp balô
mà giải bằng vét cạn thì sẽ có độ phức tạp tính toán O(2n). Trong khi đó giải bằng
quy hoạch động chỉ có độ phức tạp là O(n.m) mà thôi.
Thật vậy, gọi F(i,j) là giá trị lớn nhất thu được khi ta được chọn i đồ vật từ 1 đến i để xếp vào balô có trọng tải j. Dễ thấy là F(0,j) = F(i,0)=0. Nếu i,j>0 thì ta thấy:
- trường hợp thứ nhất: j<wi. Khi đó ta không thể đưa vật i vào balô, và giá trị lớn nhất thu được sẽ là chọn i-1 vật còn lại và trọng tải balô vẫn là j, tức là F(i,j)=F(i-1,j).
- trường hợp thứ hai: j>=wi. Trong tình huống này ta có thể chọn vật i để đưa vào balô hoặc không. Nếu không chọn thì F(i,j)=F(i-1,j) như trường hợp trên. Nếu chọn thì F(i,j)=F(i-1,j-wi) + vi. Công thức này rất dễ hiểu, vì khi ta chọn vật i thì tải trọng của balô còn lại là j-wi, ta còn i-1 vật nữa để chọn nên giá trị lớn nhất thu được là F(i- 1,j-wi) + vi. Trong 2 cách đó ta sẽ chọn cách tốt hơn. Vậy F(i,j)=max(F(i-1,j-wi) + vi, F(i-1,j)).
Công thức quy hoạch động có thể tóm tắt lại như sau: 1. F(0,j) = F(i,0)=0
2. F(i,j) = F(i-1,j) nếu j<wi
3. F(i,j)=max(F(i-1,j-wi) + vi, F(i-1,j)) nếu j>=wi.
Chương trình con tính bảng phương án sẽ thực hiện tính các giá trị i,j từ nhỏ đến lớn. Cụ thể như sau: procedure Optimize; begin for i := 0 to n do F[i,0]:=0; for j := 0 to m do F[0,m]:=0; for i := 1 to n do begin for j := 1 to m do
if j<w[i] then F[i,j] := F[i-1,j] else
F[i,j] := max(F[i-1,j], F[i-1,j-w[i]]+v[i]); end;
end;
Sau quá trình tính toán, giá trị lớn nhất thu được khi được chọn n đồ vật với balô trọng tải m sẽ là F[n,m]. Quá trình lần vết dựa vào tương quan giữa F[i,j], F[i-1,j] và
F[i-1,j-w[i]]+v[i] sẽ xác định được các vật được chọn. Độc giả có thể dễ dàng xây dựng chương trình con truy vết và chứng minh được thuật giải quy hoạch động này có độ phức tạp tính toán là O(n.m). Chi phí bộ nhớ cũng là O(n.m).
Trong phần sau trình bày về những cải tiến đối với quy hoạch động, chúng tôi sẽ trình bày những cách cài đặt các thuật toán trên với chi phí bộ nhớ thấp hơn. Trước khi kết thúc, chúng tôi sẽ trình bày một bài toán quy hoạch động kinh điển nữa, đó là bài toán nhân ma trận.