Dưới đây là một số bài toán sử dụng phương pháp Quy hoạch động cơ bản mà mình đã hoặc đã từng làm, sol có thể còn sai sót mong nhận được sự thông cảm từ bạn đọc.
Link chấm bài: https://oj.vnoi.info/problem/liq
Cho mảng số nguyên gồm phần tử, hãy tìm dãy con (có thể không liên tiếp) tăng dài nhất của mảng .
Ví dụ: thì ta có độ dài dãy con tăng dài nhất là .
Tuy ý tưởng này không phải DP nhưng thôi cứ note đây :v
Link chấm bài: https://oj.vnoi.info/problem/lis
Đề tương tự như trên nhưng ta sẽ có nhiều phương pháp để tối ưu thời gian chạy thuật toán như Chặt nhị phân, Fenwick tree,…
Ta khởi tạo mảng để lưu dãy con tăng dài nhất, từ đó ta rút ra được nhận xét như sau:
Ban đầu vì dãy con tăng dài nhất đầu tiên chỉ chứa một phần tử.
Tiến hành duyệt từ trở đi, khi đó xảy ra 3 trường hợp:
Nếu thì ta cập nhật để đảm bảo rằng dãy con tăng dài nhất bắt đầu từ và chỉ chứa một phần tử.
Nếu lớn hơn phần tử cuối cùng đang xét ở mảng thì ta sẽ tăng biến lên đơn vị và gán . Khi đó, chính là phần tử lớn nhất trong dãy con tăng có độ dài .
Nếu nằm giữa các phần tử của dãy thì khi đó ta cần tìm vị trí chính xác của nó trong để cập nhật. Rõ ràng nếu là phần tử lớn nhất trong dãy thì ta chỉ cần tăng lên đơn vị và gán (như trường hợp 2).
Tuy nhiên, nếu không phải là phần tử lớn nhất trong thì ta cần tìm vị trí chính xác để chèn vào sao cho dãy vẫn duy trì tính chất tăng dần. Để làm được điều này, ta sử dụng chặt nhị phân kết quả.
Ta tiến hành tìm vị trí sao cho là phần tử đầu tiên trong dãy lớn hơn hoặc bằng , khi tìm được ta gán .
Link chấm bài:
Ngày xửa ngày xưa có một nàng công chúa dễ thương tên là Farida sống trong lâu đài cùng với cha, mẹ và chú của mình. Trên đường đến lâu đài có nhiều quái vật. Mỗi người trong số họ có một số tiền vàng. Mặc dù chúng là quái vật nhưng chúng sẽ không làm bạn bị thương. Thay vào đó, chúng sẽ đưa cho bạn những đồng tiền vàng, nhưng quái vật thứ chỉ đưa vàng cho bạn khi và chỉ khi bạn không lấy bất kì đồng xu nào từ quái vật thứ .
Dữ liệu nhập:
Kết quả:
Sample input:
Sample output:
Gọi là số lượng đồng xu nhiều nhất khi lấy đến quái vật thứ .
Dễ dàng nhận ra trường hợp nghĩa là không có con quái vật nào hết thì đồng nghĩa với việc số lượng đồng xu nhiều nhất ta có thể đạt được là .
Với thì ta duyệt từ , khi đó có 2 trường hợp:
Ta sẽ lấy đồng xu của quái vật thứ , thì ta sẽ không lấy được xu của quái vật thứ .
Ta sẽ không lấy xu của quái vật thứ thì khi đó ta sẽ lấy đồng xu của con quái vật thứ đưa cho ta là .
Công thức quy hoạch động:
Link chấm bài :
Cần chuyển hết gói tin trên một mạng gồm kênh truyền. Biết chi phí chuyển gói trên kênh là ().
Yêu cầu: cho biết một phương án chuyển gói tin với chi phí thấp nhất.
Dữ liệu:
Dòng đầu tiên gồm hai số và ().
Dòng thứ trong dòng tiếp theo, mỗi dòng gồm dãy số nguyên dương trong đó là chi phí chuyển gói tin trên kênh .
Kết quả:
Dòng đầu tiên: tổng chi phí thấp nhất theo phương án tìm được.
Dòng thứ trong dòng tiếp theo là số lượng gói tin chuyển trên kênh .
Sample input:
Sample output:
Giải thích: với gói tin, kênh và chi phí cho trước, trong đó là chỉ số dòng (số gói tin), là chỉ số cột (kênh) thì cách chuyển sau đây cho kết quả chi phí thấp nhất là .
Kênh | Số gói tin | Chi phí |
---|---|---|
1 | 0 | 0 |
2 | 4 | 1 |
3 | 1 | 1 |
4 | 0 | 0 |
Gọi là chi phí nhỏ nhất để tạo ra gói sử dụng kênh , nên đáp án là .
Giả sử tại kênh phải sử dụng gói thì ta sẽ duyệt for để tính số gói tại kênh . Vậy thì trạng thái lúc này đang là gói tại kênh nên ta dễ dàng suy ra được trạng thái trước đó sẽ là gói tại kênh .
Công thức quy hoạch động: .
Ở bài này cần phải truy vết nên ta sẽ khởi tạo một mảng 2 chiều và 1 vector để làm điều đó. Ta khởi tạo biến và gán cho nó bằng vết cuối cùng sau khi quy hoạch động, và ta sẽ cập nhật
kênh thứ , nghĩa là lưu số gói đã dùng tại kênh và cứ như thế ta truy vết tiếp.