5. Bố cục đề tài
2.2. Bài toán balo
2.2.1. Phát biểu bài toán
Một kẻ trộm đột nhập vào một cửa hiệu tìm thấy có n mặt hàng có trọng lượng p và giá trị v khác nhau, nhưng hắn chỉ mang theo một balo có sức chứa về trọng lượng tối đa là M. Vậy kẻ trộm nên bỏ vào balo những món nào để đạt giá trị lớn nhất trong khả năng mà hắn có thể mang đi được.
0 1 2 3 4 5 6 7 0 -1 -1 -1 -1 -1 -1 -1 1 0 1 2 4 9 19 38 77 2 -1 2 5 10 21 42 85 171 3 -1 5 10 21 42 84 171 342 4 -1 10 21 42 85 171 342 684 5 -1 21 42 85 170 343 686 1373
Dữ liệu vào: Ghi trong tệp tin văn bản Balo.inp gồm:
- Dòng đầu tiên ghi số mặt hàng n và M trọng lượng Balo của tên trộm cách nhau một khoảng trắng.
- n dòng tiếp theo, trên mỗi dòng ghi p và v mỗi mặt hàng, các số này cách nhau một khoảng trắng.
Dữ liệu ra: Ghi trong tệp tin văn bản Balo.out gồm:
- Dòng đầu tiên ghi giá trị lớn nhất trong việc chọn n mặt hàng với trọng lượng tối đa là M.
- Các dòng tiếp theo ghi số thứ tự các mặt hàng được chọn. Ví dụ: Balo.inp Balo.out 5 6 1 2 3 2 3 3 2 4 1 1 9 1 3 4
2.2.2. Phân tích, xử lý bài toán và lập hệ thức truy hồi
Ta chia nhỏ bài toán thành các bài toán con với các mặt hàng {1, 2… i} (1 ≤ i ≤ n) và trọng lượng tối đa của Balo là j (1 ≤ j ≤ M).
Với trọng lượng tối đa là j thì việc chọn các mặt hàng từ {1, 2 …i} sẽ có 2 khả năng:
- Nếu không chọn mặt hàng thứ i thì giá trị lớn nhất có thể bằng cách chọn các mặt hàng từ {1, 2… i – 1} với trọng lượng tối đa là j.
v(i, j) = v(i - 1, j)
- Nếu chọn mặt hàng thứ i thì giá trị lớn nhất có thể bằng tổng giá trị của nó và giá trị lớn nhất trong việc chọn các mặt hàng {1, 2… i – 1} với trọng lượng tối đa là j – pi.
v(i, j) = vi + v(i - 1, j - pi)
2.2.3. Thuật toán
Khởi tạo mảng hai chiều có số dòng n và số cột là M, giá trị mỗi phần tử là giá trị lớn nhất trong việc chọn các mặt hàng từ {1, 2… i} với trọng lượng tối đa là j, được tính theo công thức:
v(i, j) = v (i - 1, j) hoặc
v(i, j) = vi + v(i - 1, j - pi) Ngoại lệ đối với các phần tử ở hàng 0 và cột 0:
- v(0, j) là giá trị lớn nhất trong việc chọn 0 mặt hàng với trọng lượng tối đa là j => v(0, j) = 0.
- v(i, 0) là giá trị lớn nhất trong việc chọn i mặt hàng với trọng lượng tối đa là 0 => v(i, 0) = 0.
Truy vết, sử dụng thuật toán đệ quy trên mảng hai chiều (n, M) để tìm các mặt hàng được chọn, bắt đầu từ mặt hàng thứ n và sau đó giảm dần đến mặt hàng thứ i.
- Nếu giá trị tại ô (n - 1, M - pi) + vi lớn hơn giá trị tại ô (n - 1, M) thì tiếp tục đệ quy từ ô (n - 1, M - pi).
- Ngược lại, đệ quy từ ô (n - 1, M).
2.2.4. Thiết kế chương trình
B1: Khởi tạo mảng something một chiều với độ dài là n và giá trị các phần
tử được đọc vào từ file Balo.inp.
B2: Khởi tạo mảng balo hai chiều với số dòng và số cột lần lượt là n, M
(được đọc vào từ file Balo.inp) và giá trị các phần tử được khởi tạo như sau: - Các phần tử ở dòng 0 và cột 0 được khởi tạo giá trị là 0.
- Các phần tử còn lại được tính như sau:
For i từ 1 đến n
For j từ 1 đến M If pi ≤ j
If vi + balo[i - 1][j - pi] > balo[i - 1][j] balo[i][j] = vi + balo[i - 1][j - pi]
Else
balo[i][j] = balo[i - 1][j]
Else
balo[i][j] = balo[i - 1][j]
B3: Ghi giá trị phần tử balo[n][M] (giá trị lớn nhất trong việc chọn n mặt hàng với trọng lượng tối đa của balo là M) vào file Balo.out.
B4: Truy vết, sử dụng thuật toán đệ quy theo phần tử (n, M) If n = 0 Thoát khỏi hàm Else If pn <= M If vn + giá trị phần tử (n - 1, M – pn) > giá trị phần tử (n - 1, M) Đệ quy theo phần tử (n - 1, M – pn)
Ghi n vào file Balo.out
Else
Đệ quy theo phần tử (n - 1, M)
Else
Đệ quy theo phần tử (n - 1, M)
2.2.5. Ví dụ
Sau khi đọc n mặt hàng từ file Balo.inp và mảng hai chiều balo được khởi tạo và tính toán: Đệ quy để tìm các mặt hàng được chọn từ phần tử thứ (5, 6). Vì p5 ≤ M (1 ≤ 6) => Xét ô (4, 6) > ô (4, 5) + 1 (9 > 7 + 1), tiếp tục đệ quy theo phần tử (4, 6). Vì p4 ≤ M (2 ≤ 6) => Xét ô (3, 6) < ô (3, 4) + 4 (5 < 5 + 4), ghi nhận, tiếp tục đệ quy theo phần tử (3, 4). Vì p3 ≤ M (3 ≤ 4) => Xét ô (2, 4) < ô (2, 1) + 3 (4 < 2 + 3), ghi nhận, tiếp tục đệ quy theo phần tử (2, 1).
Vì p2 ≤ M (3 > 1) => Tiếp tục đệ quy theo phần tử (1, 1).
Vì p1 ≤ M (1 ≤ 1) => Xét ô (0, 1) < ô (0, 0) + 2 (0 < 0 + 2), ghi nhận, tiếp tục đệ quy theo phần tử (0, 0). 0 1 2 3 4 5 6 0 0 0 0 0 0 0 0 1 0 2 2 2 2 2 2 2 0 2 2 2 4 4 4 3 0 2 2 3 5 5 5 4 0 2 4 6 6 7 9 5 0 2 4 6 7 7 9
Vì n = 0 quá trình đệ quy kết thúc. => Các mặt hàng được chọn: 1, 3, 4.