Thử xem code này được không? Ở đây chỉ viết gợi ý, Khách viếng thăm hãy hoàn thiện thêm input, output nha. Tôi thì cố gắng thi lấy 5 điểm thôi, còn bài dạng này nhường các bạn giỏi, cũng viết gợi ý để các bạn làm cho nó tốt nha:
1. Mô hình
Cho dãy X
1, X
2,.. Xn. Hãy tìm một dãy con tăng có nhiều phần tử nhất của dãy.
Đặc trưng:
i) Các phần tử trong dãy kết quả chỉ xuất hiện 1 lần. Vì vậy phương pháp làm là ta sẽ dùng vòng FOR duyệt qua các phần tử Xi trong dãy, các phần tử trong dãy có thể được chọn nhiều lần nên ta thực hiện bằng phương pháp cho giá trị cần quy đổi tăng dần từng đơn vị.
ii) Thứ tự của các phần tử được chọn phải được giữ nguyên so với dãy ban đầu.
Đặc trưng này có thể mất đi trong một số bài toán khác tùy vào yêu cầu cụ thể. Chẳng hạn bài Tam giác bao nhau.
2. Công thức quy hoạch động QHĐ
Hàm mục tiêu : f = độ dài dãy con.
Vì độ dài dãy con chỉ phụ thuộc vào 1 yếu tố là dãy ban đầu nên bảng phương án là bảng một chiều. Gọi L(i) là độ dài dãy con tăng dài nhất, các phần tử lấy trong miền từ X
1 đến X
i và phần tử cuối cùng là X
i.
Nhận xét với cách làm này ta đã chia 1 bài toán lớn (dãy con của n số) thành các bài toán con cùng kiểu có kích thước nhỏ hơn (dãy con của dãy i số). Vấn đề là công thức truy hồi để phối hợp kết quả của các bài toán con.
Ta có công thức QHĐ để tính L(i) như sau:
• L(1) = 1. (Hiển nhiên)
• L(i) = max (1, L(j)+1 với mọi phần tử j: 0 < j < i và X
j ≤ X
i).
Tính L(i) : phần tử đang được xét là Xi . Ta tìm đến phần tử Xj < Xi có L(j) lớn nhất. Khi đó nếu bổ sung Xi vào sau dãy con ...Xj ta sẽ được dãy con tăng dần dài nhất xét từ X
1...Xi.
A)
- Dãy con có nhiều phần tử tăng nhất:
FOR i := 1 TO n DO
L[i] := 1;
FOR j := 1 TO i – 1 DO
IF (X[j] ≤ X[i]) & (L[i] < L[j] + 1) THEN L[i] := L[j] + 1;
B)
- Dãy con có tổng lớn nhất:
FOR i := 1 TO n DO
S[i] := X[i];
FOR j := 1 TO i – 1 DO
IF(X[j] ≤ X[i]) & (S[i] < S[j] + X[i]) THEN S[i] := S[j] + X[i];
[You must be registered and logged in to see this link.].