Lời nói đầuLập trình động còn gọi là phương pháp quy hoạch động là một kĩ thuật rất hiệu quả giải quyết nhiều bài toán tin học, đặc biệt là những bài toán tối ưu.. Tài liệu gồm 4 chương:
Trang 1Lời nói đầu
Lập trình động (còn gọi là phương pháp quy hoạch động) là một kĩ thuật rất
hiệu quả giải quyết nhiều bài toán tin học, đặc biệt là những bài toán tối ưu Sốlượng bài toán được giải bằng lập trình động cũng rất lớn, ví dụ riêng kì thiOlympic quốc tế về Tin học IOI 2004 có tới 3 bài trong 6 bài thi có thể giải bằnglập trình động Nhiều năm gần đây, trong hầu hết các đề thi chọn HSG QG đều
có ít nhất 1 trong 3 bài có thể giải bằng phương pháp quy hoạch động
Nhóm tác giả chúng tôi biên tập tài liệu “Bài tập quy hoạch động” này
mong muốn giới thiệu lí thuyết và các bài tập từ đơn giản đến phức tạp của lậptrình động Cuốn sách sẽ là tài liệu quí báu đối với học sinh năng khiếu Tin học,sinh viên các ngành công nghệ thông tin và giáo viên môn Tin học của cáctrường THPT
Tài liệu gồm 4 chương:
Chương I: Cơ sở lý thuyết
Chương II: Một số bài tập cơ bản
Chương III: Bài tập chọn lọc
Chương IV: Một số đề tự giải
Chương I nêu rõ tư tưởng, vị trí, ứng dụng của lập trình động và cách nhậndiện các bài tập có thể giải bằng phương pháp quy hoạch động Chương II phântích và dẫn ra chương trình giải các bài toán kinh điển như: Tìm dãy con khônggiảm dài nhất, Dãy con chung dài nhất, Tìm dãy con có tổng bằng S, ….ChươngIII, chương IV giới thiệu đề bài, cách giải, chương trình của rất nhiều bài tậpchọn lọc
Chúng tôi chân thành cảm ơn các bạn đồng nghiệp đã nhận xét và góp ýcho bản thảo, trân trọng cảm ơn BGH trường THPT Chuyên Bắc Giang đã khích
lệ, tạo điều kiện cho nhóm tác giả được nghiên cứu để tài liệu sớm được ra mắtbạn đọc
Trang 2Trong quá trình biên soạn, mặc dù chúng tôi đã cố gắng, song nội dungchuyên đề ngày càng có nhiều khía cạnh mới và sâu sắc nên chắc chắn tài liệucòn nhiều hạn chế Chúng tôi rất mong được bạn đọc xa gần góp ý, để lần tái bảnsau tài liệu sẽ hoàn thiện hơn.
Mọi góp ý, xin gửi đến địa chỉ:
Nhóm Tin học Trường THPT Chuyên Bắc Giang
Trang 3Chương I: Cơ sở lý thuyết
I.1 Tư tưởng của phương pháp quy ho ạch động
I.1.1 Thuật toán chia để trị
Lập trình động cũng như chia để trị là các phương pháp giải một bài toánbằng cách tổ hợp lời giải các bài toán con của nó
Thuật toán chia để trị được coi là thuật toán thông dụng nhất trong Tin
học Khi giải một bài toán P với kích thước ban đầu nào đó nếu gặp trở ngại vìkích thước quá lớn, người ta thường nghĩ đến việc giải các bài toán tương tựnhưng với kích thước nhỏ hơn (gọi là các bài toán con của P) Tư tưởng “chia đểtrị” thường được nhắc tới như hình ảnh “bẻ dần từng chiếc đũa để bẻ gãy cả
bó đũa”
Chia để trị thực hiện “tách” một bài toán ban đầu thành các bài toán con độc lập, sau đó giải các các bài toán con này và tổ hợp dần lời giải từ bài toán
con nhỏ nhất đến bài toán ban đầu
Nhưng giải từng bài toán con như thế nào? Chúng ta có thể thực hiện mộtcách đơn giản lại “tách” bài toán con thành các bài toán con nhỏ hơn nữa, và
cứ tiến hành như vậy cho đến khi gặp các bài toán con nhỏ đến mức dễ dànggiải được Các bài toán con cùng được sinh ra sau mỗi lần “tách” được gọi làcùng mức Những bài toán con sinh ra sau hơn thì ở mức dưới (thấp hơn).Thủ tục đệ quy luôn là cách thường dùng và hiệu quả để thực hiện thuậttoán chia để trị Quá trình đệ quy lần lượt xếp dần các bài toán con vào ngănxếp bộ nhớ và sẽ thực hiện giải các bài toán con theo thứ tự ngược lại từ bàitoán đơn giản nhất trên đỉnh ngăn xếp cho đến khi giải được bài toán ban đầu
ở đáy ngăn xếp
Ví dụ: Cho mảng a[1 n] gồm các số đã sắp tăng Tìm phần tử của mảng có
giá trị bằng số x cho trước
Trang 4Xét chương trình thực hiện thuật toán tìm kiếm nhị phân (một kiểu chia
để trị rất phổ biến) để giải bài toán trên Trong chương trình chính có lời gọithủ tục tim(1,n) Sau đây là thủ tục tim(i,j):
Procedure tim(i,j : integer); {Tim x c ó trong mảng a[i j] hay không}
I.1.2 Hệ thức truy hồi
Giải bài toán thường tiến hành theo nhiều bước Kết quả của một bướcthường dựa vào kết quả của các bước thực hiện trước đó Do vậy, cần xâydựng hệ thức thể hiện quan hệ về kết quả giữa các bước gọi là hệ thức truyhồi
Ví dụ 1: Cho dãy số Fibonaci {F1, F2, …, Fn}, trong đó:
F1 = F2 = 1 và Fn = Fn-1 + Fn-2 với n > 2 (1) Tìm số hạng thứ n
Trang 5Hệ thức tính số hạng thứ n của dãy Fibonaci là hệ thức (1) đã cho sẵn
trong đề bài
Ví dụ 2: Cho một dãy N số nguyên A1, A2, …, An Hãy tìm cách xoá đi một số
ít nhất số hạng để dãy còn lại là đơn điệu hay nói cách khác hãy chọn một sốnhiều nhất các số hạng sao cho dãy B gồm các số hạng đó theo trình tự xuấthiện trong dãy A là đơn điệu
Minh hoạ cho ví dụ 2:
Dãy A: 1, 4, 10, 9, 8, 17, 11, 7, 12, 6
Dãy B: 1,4,10,11,12
Phân tích để giải bài toán ta thấy:
Khi dãy A có một phần tử a1thì dãy B có 1 phần tử
Mở rộng bài toán với dãy A có 2 phần tử, có 3 phần tử, … để tìm độ dàidãy B Ta có bài toán tổng quát: Gọi F[i] là số phần tử của dãy con B khi dãy A
có các phần tử từ 1 đến i
Dễ dàng tính được:
F[i] := 1 nếu không tồn tại j:= 1 i-1 để A[j] < A[i]
F[i] := max{F[j], j=1 i-1 thoả mãn a[j] < a[i]} + 1; (2)
Như vậy, để giải bài toán ở ví dụ 2 ta phải tiến hành qua n bước lời giải ở
bước i (i=1,2,…,n) phụ thuộc vào lời giải của i-1 bước trước đó Hệ thức (2)
chính là hệ thức truy hồi của bài toán
Trang 6Lập trình động (dynamic programming) cũng phân chia bài toán thành các bài toán con, nhưng các bài toán con phụ thuộc nhau (hay dùng từ gối nhau
cũng được), mỗi bài toán con có thể tham chiếu tới cùng một số bài toán conmức dưới (sự phân chia không có cấu trúc dạng cây xem hình 1)
Hình 1: Đồ thị bài toán con cho dãy Fibonacci Đây không phải là một cấutrúc cây mà là một đồ thị có hướng phi chu trình mô tả quan hệ giữa các bàitoán con gối nhau
Nói rằng một bài toán có các bài toán con trùng nhau có nghĩa là mỗi bài
toán con đó được sử dụng để giải nhiều bài toán lớn hơn khác nhau Ví dụ,trongdãy Fibonacci, F3 = F1 + F2 and F4 = F2 + F3— khi tính mỗi số đều phải tínhF2 Vì tính F5 cần đến cả F3 và F4, một cách tính F5 một cách ngây thơ có thể sẽphải tính F2 hai lần hoặc nhiều hơn Điều này áp dụng mỗi khi có mặt các bàitoán con gối nhau: một cách tiếp cận ngây thơ có thể tốn thời gian tính toán lạilời giải tối ưu cho các bài toán con mà nó đ ã giải
Để tránh việc đó, ta lưu trữ lời giải của các bài toán con đã giải Do vậy,nếu sau này ta cần giải lại chính bài toán đó, ta có thể lấy và sử dụng kết quả
đã được tính toán Hướng tiếp cận này được gọi là lưu trữ (trong tiếng Anhđược gọi làmemoization , không phải memorization, dù từ này cũng hợp nghĩa).
Nếu ta chắc chắn rằng một lời giải nào đó không còn cần thiết nữa, ta có thểxóa nó đi để tiết kiệm không gian bộ nhớ Trong một số trường hợp, ta còn cóthể tính lời giải cho các bài toán con mà ta biết trước rằng sẽ cần đến
Trang 7Khi giải bài toán Fibonaci cỡ i (với i tăng từ 2 đến n), ta đều sử dụng kếtquả của 2 bài toán con cỡ i-1 và i-2;
Lập trình động do nhà toán học người Mỹ là Richard Bellman (1920-1984)phát minh vào năm 1953
Lập trình động thường dùng để giải các bài toán tối ưu – bài toán yêu cầutìm một giải pháp tốt nhất trong các giải pháp có thể tìm được
Cơ sở của lập trình động trong bài toán tối ưu là nguyên lí tối ưu Bellman:
“Dãy tối ưu các quyết định trong một quá trình quyết định nhiều giai đoạn cóthuộc tính là dù trạng thái và các quyết định ban đầu bất kể thế nào, nhữngquyết định còn lại phải tạo thành một cách giải quyết tối ưu không phụ thuộcvào trạng thái được sinh ra từ những quyết định ban đầu”
I.1.4 Phương pháp quy hoạch động
Trong ngành khoa học máy tính, phương pháp quy hoạch động là mộtphương pháp giảm thời gian chạy của các thuật toán thể hiện các tính chất của
các bài toán con gối nhau và cấu trúc con tối ưu.
Tư tưởng chủ đạo của phương pháp quy hoạch động có thể tóm lược nhưsau:
Chia 1 bài toán lớn thành các bài toán con tương tự có kích thước nhỏ hơncho đến khi nhận được các bài toán con mà lời giải có thể xây dựng dễ dàng
Ta phải tìm ra mối quan hệ giữa nghiệm của bài toán với nghiệm của cácbài toán con, mối quan hệ thể hiện 1 công thức truy hồi hay một hàm gọi làcông thức quy hoạch động (hay hàm quy hoạch động)
Khi tính toán chúng ta xuất phát tính từ nghiệm các bài toán con ban đầu,sau đó kết hợp nghiệm của các bài toán con theo công th ức quy hoạch động tađược nghiệm bài toán con có cỡ lớn hơn Quá trình cứ tiếp tục như vậy chođến khi ta được nghiệm của bài toán đã cho
Trang 8Vậy: Ý tưởng cơ bản của quy hoạch động thật đơn giản: tránh tính toán
lại mọi thứ hai lần, mà lưu giữ kết quả đã tìm kiếm được vào một bảng làm giảthiết cho việc tìm kiếm những kết quả của trường hợp sau Chúng ta sẽ làmđầy dần giá trị của bảng này bởi các kết quả của những trường hợp trước đãđược giải Kết quả cuối cùng chính là kết quả của bài toán cần giải
Ví dụ: Tính số hạng thứ n của dãy Fibonaci bằng phương pháp quy hoạch
động như sau:
Nghiệm của mỗi bài toán con chỉ cần tính 1 lần và được lưu trong mảng 1chiều F Khi tìm kết quả của các bài toán cỡ lớn hơn, kết quả của các bài toáncon chỉ việc lấy ra để sử dụng
F1 := 1; F2 := 1;
For i := 3 to n do F[i] := F[i-2] + F[i-1];
I.2 Các bước thực hiện giải bài toán bằng phương pháp quy
hoạch động
I.2.1 Các bước cơ bản:
Bước 1: Phân tích tìm công thức quy hoạch động
- Tìm ra công thức nghiệm của bài toán lớn thông qua việc giải các bàitoán con
- Xác định nghiệm của bài toán con đơn giản (trong trường hợp cơ sở)
Bước 2: Thực hiện tính toán và tổ chức dữ liệu
- Đầu tiên tính nghiệm của bài toán con đơn giản (cơ sở)
(Khởi tạo giá trị ban đầu cho hàm QHĐ)
- Dựa vào hàm QHĐ đã xây dựng ta tính nghiệm của bài toán theo kíchthước lớn dần cho đến khi nhận được nghiệm của bài toán đã cho
Bước 3: Tổ chức dữ liệu và cài đặt
Trang 9- Thường dùng mảng một chiều hoặc hai chiều để lưu trữ lại các giá trịcủa các bài toán con (giá trị của hàm QHĐ)
- Ngoài ra, chúng ta phải dùng một số biến, thông thường cũng là mảng đểlưu trữ lại trạng thái của bài toán để sau này chúng ta có thể truy xuất lời giảicủa bài toán
I.2.3 Khi nào dùng phương pháp quy hoạch động?
- Khi gặp bài toán có tính chất truy hồi
- Khi lời giải bài toán ở bước sau được xây dựng thông qua lời giải bàitoán ở bước trước
- Kích thước bài toán không quá lớn
*Ưu điểm:
- Lời giải ngắn gọn, sang sủa, có tính logic cao, chương trình chạy nhanh
*Nhược điểm:
- Không phải bài nào cũng giải bằng QHĐ
- Việc tìm ra công thức QHĐ của nhiều bài toán là khó khăn
- Không có công thức chung
- Bị hạn chế về bộ nhớ vì chúng ta phải lưu trữ nghiệm của các bài toáncon
Trang 10Chương II: Một số bài tập cơ bản
Bài 1: Tìm dãy con không gi ảm nhiều phần tử nhất;
Cho dãy số nguyên có n phần tử a1, a2, …, an Một dãy con không giảm củadãy đã cho là dãy các phần tử còn lại của dãy đó sau khi ta xóa bỏ một hoặcmột số phần tử bất kì của nó, các phần tử của dãy con tạo thành dãy khônggiảm Ví dụ: dãy 1,4,10,11,12 là một dãy con không giảm của dãy 1, 4, 10, 9, 8,
17, 11, 7, 12, 6
Yêu cầu: Tìm dãy con không giảm của dãy a gồm nhiều phần tử nhất.
Dữ liệu: Vào từ file văn bản DAYCON.INP gồm:
Dòng đầu tiên ghi số N (0 < N < 105)
Các dòng tiếp theo, mỗi dòng ghi 10 số nguyên của dãy N số nguyên a1, a2, , an Dòng cuối cùng có thể ít hơn 10 số Các số trên một dòng cách nhau mộtdấu cách
Kết quả: Ghi ra file văn bản DAYCON.OUT gồm:
Số max là độ dài dãy con không giảm dài nhất tìm được
Chỉ số xuất hiện của các số hạng của dãy con trong dãy đã cho
Trang 11Bảng phương án là một mảng một chiều L để lưu trữ các giá trị của hàmQHĐ L(i) Đoạn chương trình tính các giá trị của mảng L như sau:
Trang 13Bài 2: Dãy con chung dài nhất;
Cho hai dãy số nguyên a = (a1, a2, …, aM), b = (b1, b2, …, bN), với M,N < 200
Trang 14Hãy tìm một dãy con chung c=(c1, c2, …, cK) của a và b gồm nhiều số hạngnhất Dãy con chung c nhận được bằng cách xóa đi một số số hạng của dãy a, ccũng nhận được bằng cách xóa đi một số số hạng của dãy b, sau khi xóa ở haidãy giữ nguyên thứ tự các phần tử còn lại.
Dữ liệu: Vào từ file văn bản DAYCC.INP có cấu trúc như sau:
Dòng đầu tiên ghi 2 số nguyên dương M, N
Dòng thứ 2 ghi các số a1, a2, …, aM;
Dòng thứ 3 ghi các số b1, b2, …, bN;
Kết quả: Ghi ra file văn bản DAYCC.OUT có cấu trúc:
Dòng đầu ghi số K là số lượng các số hạng của dãy con chung c (nếu không
có dãy con chung thì ghi số 0);
Trong k dòng tiếp theo, dòng thứ i (I = 1, 2, , k) ghi 2 số x, y với ý nghĩa là:
số hạng thứ i của dãy c là số hạng thứ x của dãy a và là số hạng thứ y của dãyb;
Trang 15(b(j) =b [1 j]).
Ta có công thức quy hoạch động như sau:
L(0,j)=L(i,0)=0
L(i,j) = L(i - 1,j - 1)+1 nếu a[i] = b[j]
L(i,j) = max(L(i - 1,j), L(i,j - 1)) nếu a[i] ≠ b[j]
for i:=1 to m do read(g,a[i]);
for i:=1 to n do read(g,b[i]);
close(g);
End;
Function max(x,y:integer):integer;
Begin
Trang 16if x > y then max:=x else max:=y;
End;
Procedure Build;
var i,j:integer;
Begin
for i:= 0 to m do f[i,0]:=0;
for i:= 0 to n do f[0,i]:=0;
Trang 17Begin
if f[i,j] = f[i-1,j] then dec(i)
else if f[i,j] = f[i,j-1] then dec(j);
Bài 3: Dãy con có tổng bằng S
Cho dãy a1, a2, an Tìm một dãy con của dãy đó có tổng bằng S
Dữ liệu: vào từ file văn bản "tongs.inp" có dạng :
- Dòng đầu tiên là 2 số N, S (N<200);
- Dòng thứ hai là N số Ai (i=1, 2, , N; -32000 <= Ai <=32000)
Kết quả: Ghi ra file văn bản "tongs.out" có dạng:
- Các phần tử thuộc dãy con tìm được
Trang 18Đặt L(i,t)=1 nếu có thể tạo ra tổng t từ một dãy con của dãy gồm các phần tử a 1 ,a 2 , a i Ngược lại thì L(i,t)=0 Nếu L(n,S)=1 thì đáp án của bài toán
Trang 20Bài 4: Xếp đồ vật vào ba lô (mỗi đồ vật chỉ có 1)
Một chiếc ba lô có thể chứa được một khối lượng không quá W Có N đồvật được đánh số từ 1 đến N, đồ vật i có khối lượng Ai và giá trị sử dụng Ci (i=1,
2, …,N) Hãy chọn các đồ vật để xếp vào ba lô sao cho tổng giá trị các đồ vậttrong ba lô là lớn nhất (nếu có thể xếp được)
Dữ liệu: vào từ file văn bản BALO.INP có cấu trúc như sau:
Dòng đầu ghi 2 số nguyên dương N, W (0 < N,W < 100)
Dòng thứ i+1, với i=1,2, ,N, ghi 2 số nguyên dương Ai và Ci tương ứng làkhối lượng và giá trị sử dụng của đồ vật thứ I (0 < Ai, Ci< 256)
Kết quả: Ghi ra file văn bản BALO.OUT có cấu trúc:
Dòng đầu ghi tổng giá trị sử dụng lớn nhất tìm được
Trang 21Dòng 2 ghi chỉ số các đồ vật được xếp vào ba lô.
L(n,m) sẽ là đáp số của bài toán (là giá trị lớn nhất có được nếu chọn n vật
và tổng khối lượng không vượt m)
Công thức tính L(i,t) như sau:
L(i,0)=0; L(0,t)=0
L(i,t)=L(i–1,t) nếu t<Ai
L(i,t)=max(L(i–1,t), L(i–1,t–ai)+bi) nếu t ≥ ai Trong đó: L(i–1,t) là giá trị cóđược nếu không đưa vật i vào balô, L(i–1,t–ai)+bi là giá trị có được nếu chọn vậti
Ta có thể dùng một mảng 2 chiều để lưu bảng phương án, tuy nhiên dựatrên nhận xét rằng để tính dòng i của bảng phương án chỉ cần dòng i–1, ta chỉcần dùng 2 mảng một chiều P và L có chỉ số từ 0 đến m để lưu 2 dòng đó Đoạnchương trình con tính bảng phương án như sau
Trang 24gt[j]:=gt[j-a[i]]+c[i]; truoc[j]:=i;
if gt[j]>kq then
begin
kq:=gt[j];luu:=j;end;
Trang 26Chương III: Bài tập chọn lọc
Bài 5: Bố trí phòng họp;
Có n cuộc họp đánh số từ 1 đến n đăng ký làm việc tại một phòng hộithảo Cuộc họp i cần được bắt đầu tại thời điểm si và kết thúc tại thời điểm fi Hỏi có thể bố trí phòng hội thảo phục vụ được nhiều nhất bao nhiêu cuộc họpsao cho khoảng thời gian làm việc của hai cuộc họp được nhận phục vụ chỉ cóthể giao nhau tại đầu mút
Dữ liệu: vào từ file văn bản ACTIVITY.INP
Dòng dầu tiên chứa số nguyên dương n (n <= 1000000)
Dòng thứ i trong số n dòng tiếp theo chứa hai số nguyên dương si, fi (si, fi
<= 32000), i=1,2, …,n
Kết quả: Ghi ra file văn bản ACTIVITY.OUT
Dòng đầu tiên ghi số k là số lượng cuộc họp được chấp nhận phục vụ;Mỗi dòng trong K dòng tiếp theo ghi chỉ số của một trong k cuộc họp đượcchấp nhận
Trang 27* Hướng dẫn:
Sắp xếp các cuộc họp tăng dần theo thời điểm kết thúc (bi) Thế thì cuộchọp i sẽ bố trí được sau cuộc họp j nếu và chỉ nếu j < i va` bj≤ ai Yêu cầu bố tríđược nhiều cuộc họp nhất có thể đưa về việc tìm dãy các cuộc họp dài nhấtthoả mãn điều kiện trên
Trang 30Bài 6: Cho thuê máy tính;
Tại thời điểm 0, ông chủ cho thuê máy tính nhận được đơn đặt hàng thuê
sử dụng của N khách hàng Các khách hàng đư ợc đánh số từ 1 đến N Kháchhàng i cần sử dụng máy từ thời điểm di đến thời điểm ci (di và ci là các sốnguyên và 0 < di < ci < 1000000000), và s ẽ trả tiền sử dụng máy là pi (pinguyên, 0 < pi < 10000000);
Yêu cầu: Hãy xác định xem ông chủ cần nhận phục vụ những khách hàng
nào sao cho khoảng thời gian sử dụng máy tính của hai khách hàng được nhậnphục vụ bất kì không giao nhau và tổng tiền thu được từ phục vụ là lớn nhất
Dữ liệu: vào từ file văn bản RENTING.INP Dòng đầu tiên ghi số N (0 < N <
1000) Dòng thứ i trong N dòng tiếp theo ghi ba số di, ci, pi cách nhau bởi dấutrống, i=1,2, ,N
Trang 31Kết quả: Ghi ra file văn bản RENTING.OUT Dòng đầu tiên ghi hai số
nguyên dương theo thứ tự là số lượng khách hàng nhận được phục vụ và tổngtiền thu được Dòng tiếp theo ghi chỉ số của khách hàng được phục vụ
Trang 32tg:=b[j];b[j]:=b[j -1];b[j-1]:=tg; tg:=a[j];a[j]:=a[j -1];a[j-1]:=tg; tg:=cs[j];cs[j]:=cs [j-1];cs[j-1]:=tg;
Trang 33tg:=c[j];c[j]:=c[j -1];c[j-1]:=tg; ok:=false;
Trang 34Bài 7: Nối điểm
Trên hai đường thẳng song song L1 và L2 ngư ời ta đánh dấu trên mỗiđường N điểm Các điểm trên đường thẳng L1 được đánh số từ 1 đến N từ trái
Trang 35sang phải, còn các điểm trên đường thẳng l2 được đánh số p1, p2, …, pN cũng
từ trái qua phải với p1, p2, …, pN là một hoán vị của 1, 2, …, N (Hình vẽ dướiđây cho một ví dụ khi N=9):
Ta gọi các số gán cho các điểm là số hiệu của chúng Cho phép nối haiđiểm trên hai đường thẳng có cùng số hiệu
Yêu cầu tìm cách nối được nhiều cặp điểm nhất với điều kiện các đoạnnối không được cắt nhau
Dữ liệu: vào từ file văn bản WIRE.INP có cấu trúc như sau:
Dòng đầu tiên chứa số nguyên dương N (N < 1000);
Dòng thứ hai chứa các số nguyên p1, p2, …, pN cách nhau b ởi dấu trắng;
Kết quả: Ghi ra file văn bản WIRE.OUT có cấu trúc:
Dòng đầu tiên chứa số k là số lượng các đoạn nối tìm được;
Dòng tiếp theo chứa k số hiệu của các đầu mút của các đoạn nối được ghitheo thứ tự tăng dần
Trang 38Bài 8: Dãy con đổi chiều, đối dấu dài nhất;
Cho dãy a1, a2, an Hãy tìm dãy con đổi chiều dài nhất của dãy đó Dãycon con đổi dấu ai1,ai2, aik phải thoả mãn các điều kiện sau:
ai1 < ai2> ai3 < hoặc ai1 > ai2 < ai3 > các chỉ số phải cách nhau ít nhất L: i2
- i1≥ L, i3-i2≥ L chênh lệch giữa 2 phần tử liên tiếp nhỏ hơn U: |ai1- ai2| ≤ U,
|ai2- ai3| ≤ U
Ví dụ: Cho dãy 10 phần tử: -1, 3, -4, 13, 6, 9, -2, 12, -3, 15 và L=2 và U=3
Có 1 dãy con đổi chiều dài nhất là: -1, -4, -2, -3
Dữ liệu: Vào từ file văn bản DOICHIEU.INP có cấu trúc như sau:
Dòng đầu tiên ghi 3 số nguyên dương n, L, U (n <105; 1<L<n-1; 0 < U <1000);
Các dòng tiếp theo ghi n số của dãy a; (|ai| <= 32000);
Kết quả: Ghi ra file văn bản DOICHIEU.OUT có cấu trúc như sau:
Dòng đầu là độ dài dãy con đổi chiều dài nhất tìm được;
Chỉ số các phần tử của dãy con tìm được trong dãy ban đầu;
Trang 40truoc1[i]:=j;