Nguồn: Topcoder, VNOI Wiki
(Intermediate & Upper Intermediate & Advanced coming soon.)
Có rất nhiều bài toán được áp dụng quy hoạch động (QHĐ) (Dynamic Programming). QHĐ là một trong những kĩ thuật quan trọng. Bài viết này sẽ giúp bạn hiểu được QHĐ thông qua các ví dụ cụ thể.
Note: Trong bài này có thể có nhiều phần bạn đã biết, bạn hoàn toàn có thể chuyển qua đọc phần khác.
Beginner
Quy hoạch động là gì ?
QHĐ là kĩ thuật được được dùng khi có một công thức và một (hoặc một vài) trạng thái bắt đầu. Một bài toán được tính bởi các bài toán nhỏ hơn đã tìm ra trước đó. QHĐ có độ phức tạp đa thức nên sẽ chạy nhanh hơn quay lui và duyệt trâu.
Để hiểu rõ hơn hãy xem ví dụ sau:
Cho đồng xu và giá tiền của mỗi đồng , và số . Tìm số đồng xu nhỏ nhất để tổng giá trị của chúng bằng (số lượng đồng xu không giới hạn).
Bây giờ chúng ta sẽ xây dựng thuật giải:
Đầu tiên, cần tìm một trạng thái của bài toán.
Trạng thái là gì ?
Trạng thái là một trường hợp, một bài toán con của bài toán lớn.
Ví dụ, trạng thái trong bài này là số lượng xu nhỏ nhất để tổng bằng , với . Để tìm ra trạng thái , cần phải tìm tất cả các trạng thái mà . Một khi đã tìm ra trạng thái , ta có thể dễ dàng tìm ra trạng thái của .</p>
Làm thế nào để tìm được ?
Với mỗi , , tìm số đồng xu nhỏ nhất để tổng bằng . Giả sử nó bằng . Nếu nhỏ hơn số lượng đồng xu hiện tại cho tổng thì ta cập nhập nó bằng .
Sau đây là ví dụ: Cho các đồng xu với giá tiền . Và .
Đầu tiên, ta bắt đầu từ trạng thái , chúng ta có . Xét đến tổng . Có duy nhất đồng xu nhỏ hơn hoặc bằng tổng , nên ta có
. Xét đến tổng . Cũng giống như tổng trước, chỉ có đổng xu , có
Đến tổng . Lần này có đồng xu là và . - Nếu ta chọn đồng , ta có
- Nếu ta chọn đồng 3, ta có
Rõ ràng là nên ta chọn đồng và Xét tiếp đến tổng , rồi đến bằng cách như trên.
Mã giả:
Gán Min[i] bằng dương vô cùng với mọi i
Min[0]=0
For i = 1 to S
For j = 0 to N - 1
If (Vj<=i AND Min[i-Vj]+1<Min[i])
Then Min[i]=Min[i-Vj]+1
Output Min[S]
Đây là lời giải cho tất cả các tổng:

Vậy là chúng ta đã tìm được lời giải cho đồng xu tổng bằng . Dựa vào bảng trên, ta có thể truy vết lại được những đồng xu nào được chọn để tối ưu bài toán. Bài QHĐ trên còn có một cách tiếp cận khác nữa. Lần này, ta sẽ không tính liên tiếp các tổng. Bắt đầu từ trạng thái . Thử nhét đồng xu thứ vào các tổng đã tính. Nếu như tổng có số đồng xu ít hơn số đồng xu hiện tại thì tiến hành cập nhật. Rồi tiếp tục thử với đồng thứ cho đến khi thử hết các đồng. Ví dụ, nhét đồng (giá trị ) vào tổng ta có tổng . Vì ta chưa tính tổng nên . Nhét đồng vào tổng ta có . Tiếp tục làm như vậy với các tổng còn lại. Sau đồng , ta nhét đồng (giá trị ) vào tổng ta được , mà , ta cập nhật . Tiếp tục nhét đồng vào các tổng còn lại, cũng như thử nhét các đồng xu khác.
Elementary
Bây giờ, chúng ta cùng đến một khái niệm mới, công thức truy hồi (recurrent relation), mối liên hệ giữa những trạng thái.
Ví dụ: Cho một dãy số - . Tìm dãy con không giảm dài nhất.
Ta quy định trạng thái là dãy con không giảm dài nhất kết thúc tại . Với và , tính được khi tồn tại (vì đây là dãy không giảm). Khi đó . Tiếp tục tính như vậy cho đến khi đến được trạng thái .</p>
Hãy xem bảng sau với dãy: :

Bài luyện tập: Cho đồ thị vô hướng có đỉnh và các cạnh có trọng số dương. Tìm đường đi ngắn nhất từ đỉnh đến đỉnh hoặc thông báo không tồn tại đường đi. Gợi ý: Tại mỗi bước, chọn ra trong số các đỉnh chưa thăm mà có đường đi từ , chọn ra đỉnh có đường đi ngắn nhất.
Các bài ví dụ khác:
Bình luận