Trong thực tế, ta thờng gặp một số bài toán tối u loại sau: Có một đại lợng fhình thành trong một quá trình gồm nhiều giai đoạn và ta chỉ quan tâm đến kết quảcuối cùng là trị của f phải
Trang 1II Một số bài toán tiêu biểu
(Phát biểu, phân tích thuật toán và tổ chức dữ liệu, chơng trình)
III Các bài tập luyện tập
mà cách giải bằng quy hoạch động tỏ ra không thích hợp
Trong thực tế, ta thờng gặp một số bài toán tối u loại sau: Có một đại lợng fhình thành trong một quá trình gồm nhiều giai đoạn và ta chỉ quan tâm đến kết quảcuối cùng là trị của f phải lớn nhất hoặc nhỏ nhất, ta gọi chung là giá trị tối u của f.Giá trị của f phụ thuộc vào những đại lợng xuất hiện trong bài toán mà mỗi bộ giátrị của chúng đợc gọi là một trạng thái của hệ thống và cũng phụ thuộc vào cáchthức đạt đợc giá trị f trong từng giai đoạn mà mỗi cách thức đợc gọi là một điềukhiển Đại lợng f thờng đợc gọi là hàm mục tiêu và quá trình đạt đợc giá trị tối ucủa f đợc gọi là quá trình điều khiển tối u
Bellman phát biểu nguyên lý tối u (cũng còn gọi là nguyên lý Bellman) nh sau:
" Với mỗi quá trình điều khiển tối u, đối với trạng thái bắt đầu A0, nếu giữa chừng
ta đi đến một trạng thái A nào đó thì phần quá trình đó kể từ trạng thái A xem nhtrạng thái bắt đầu cũng là tối u."
Chú ý rằng nguyên lý này đợc thừa nhận và không chứng minh
Phơng pháp tìm điều khiển tối u theo nguyên lý Bellman thờng đợc gọi là quyhoạch động Thuật ngữ này nói lên đợc thực chất của quá trình điều khiển là động:
Trang 2có thể trong một số bớc đầu tiên lựa chọn điều khiển tối u dờng nh không tốt nhngtựu chung cả quá trình lại là tốt nhất.
Ta có thể giải thích ý này qua bài toán sau:
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 tơng đơng 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ất hiện trong dãy A là đơn
điệu
Quá trình chọn dãy B đợc điều khiển qua N giai đoạn để đạt đợc mục tiêu là sốlợng số hạng của dãy B là nhiều nhất, điều khiển ở giai đoạn i thể hiện việc chọnhay không chọn Ai vào dãy B
Giả sử dãy đã cho là 1 8 10 2 4 6 7 Nếu ta chọn lần l ợt 1, 8, 10 thì chỉchọn đợc 3 số hạng nhng nếu bỏ qua 8 và 10 thì ta chọn đợc 5 số hạng 1, 2, 4, 6,
7
Khi giải một số bài toán bằng cách “chia để trị” , chuyển việc giải bài toán kíchthớc lớn về việc giải nhiều bài toán cùng kiểu có kích thớc nhỏ hơn Các thuật toánnày thờng đợc thể hiện bằng các chơng trình con đệ quy Khi đó, trên thực tế,nhiều kết quả trung gian phải tính nhiều lần
Vậ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ọithứ hai lần, mà lu giữ kết qủa đã tìm kiếm đợc vào một bảng làm giả thiết cho việctì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ủabả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ùngchính là kết quả của bài toán cần giải Nói cách khác phơng pháp quy hoạch động
đã thể hiện sức mạnh của nguyên lý chia để trị đến mức cực độ
Quy hoạch động là kỹ thuật thiết kế bottom-up (từ dới lên) Nó đợc bắt đầu vớinhững trờng hợp con nhỏ nhất (thờng là đơn giản nhất và giải đợc ngay) Bằng
cách tổ hợp các kết quả đã có (không phải tính lại) của các trờng hợp con, sẽ đạt
tới kết quả của trờng hợp có kích thớc lớn dần lên và tổng quát hơn, cho đến khicuối cùng đạt tới lời giải của trờng hợp tổng quát nhất
Trong một số trờng hợp, khi giải một bài toán A, trớc hết ta tìm họ bài toánA(p) phụ thuộc tham số p (có thể p là một véc tơ) mà A(p0)=A với p0 là trạng tháiban đầu của bài toán A Sau đó tìm cách giải họ bài toán A(p) với tham số p bằngcách áp dụng nguyên lý tối u của Bellman Cuối cùng cho p=p0 sẽ nhận đợc kếtquả của bài toán A ban đầu
2 Các bớc thực hiện quy hoạch động
Bớc 1: Lập hệ thức
Trang 3 Dựa vào nguyên lý tối u tìm cách chia quá trình giải bài toán thành từng giai
đoạn sau đó tìm hệ thức biểu diễn tơng quan quyết định của bớc đang xử lý vớicác bớc đã xử lý trớc đó Hoặc tìm cách phân rã bài toán thành các "bài toáncon" tơng tự có kích thớc nhỏ hơn, tìm hệ thức nêu quan hệ giữa kết quả bàitoán kích thớc đã cho với các kết quả của các "bài toán con" cùng kiểu có kíchthớc nhỏ hơn của nó nhằm xây dựng phơng trình truy toán (dạng hàm hoặcthủ tục đệ quy)
.Về một cách xây dựng phơng trình truy toán:
Ta chia việc giải bài toán thành N giai đoạn Mỗi giai đoạn i có trạng tháiban đầu của nó là t(i) và chịu tác động điều khiển d(i) sẽ biến thành trạng tháitiếp theo t(i+1) của giai đoạn i+1 (i=1,2, ,n-1) Theo nguyên lý tối u củaBellman thì việc tối u giai đoạn cuối cùng không làm ảnh hởng đến kết quảtoàn bài toán Với trạng thái ban đầu là t(N) sau khi làm giai đoạn N tốt nhất ta
có trạng thái ban đầu của giai đoạn N-1 là t(N-1) và tác động điều khiển củagiai đoạn N-1 là d(N-1), có thể tiếp tục xét đến giai đoạn N-1 Sau khi tối u giai
đoạn 1 ta lại có t(2) và d(2) và lại có thể tiến hành tối u giai đoạn
N-2 cho đến khi các giai đoạn từ N giảm đến 1 đợc tối u thì coi nh hoàn thànhbài toán Gọi giá trị tối u của bài toán tính đến giai đoạn k là Fk, giá trị tối ucủa bài toán tính riêng ở giai đoạn k là Gk thì
Fk = Fk-1 + Gk
Hay là:
Fk(t(k)) = Max { Gk(t(k), d(k)) + Fk-1 (t(k-1))} (*) d(k)
Bớc 2: Tổ chức dữ liệu và chơng trình
Tổ chức dữ liệu sao cho đạt các yêu cầu sau:
a- Dữ liệu đợc tính toán dần theo từng bớc
b- Dữ liệu đợc lu trữ để giảm lợng tính toán lặp lại
c- Kích thớc miền nhớ dành cho lu trữ dữ liệu càng nhỏ càng tốt, kiểu dữ liệu đợcchọn phù hợp, nên chọn đơn giản dễ truy cập
Trang 4Trong một số trờng hợp có thể thay mảng 2 chiều với các giá trị phần tử chỉnhận giá trị 0, 1 bởi mảng 2 chiều mới bằng cách dùng kỹ thuật quản lý bít.
3 Hạn chế của quy hoạch động
Việc tìm công thức, phơng trình truy toán hoặc tìm cách phân rã bài toán nhiềukhi đòi hỏi sự phân tích tổng hợp rất công phu, dễ sai sót, khó nhận ra nh thếnào là thích hợp, đòi hỏi nhiều thời gian suy nghĩ Đồng thời không phải lúcnào kết hợp lời giải của các bài toán con cũng cho kết quả của bài toán lớn hơn
Khi bảng lu trữ đòi hỏi mảng hai, ba chiều thì khó có thể xử lý dữ liệu vớikích cỡ mỗi chiều lớn hàng trăm
Có những bài toán không thể giải dợc bằng quy hoạch động
4 Một vài ví dụ
Ví dụ 1: Tính tổ hợp chập k của n.
Chúng ta có ngay công thức truy hồi quen thuộc là:
Nếu chúng ta tính tổ hợp chập k của n trực tiếp bằng hàm:
n k C
C C
k k
k
, 0
1
0
1 1
Trang 5thì nhiều lần sẽ phải tính đi tính lại giá trị C(i,j) (i<n) (j<k) Do đó thời gian thựchiện của thuật toán này lớn theo sự lặp lại Chúng ta cũng gặp hiện tợng tơng tựkhi tính dãy số Fibonacci.
Ngợc lại nếu sử dụng bảng chứa các kết quả trung gian (bảng có dạng tam giácPascal) chúng ta sẽ đạt đợc một thuật toán hiệu suất hơn Bảng sẽ đợc làm đầy dầntheo từng dòng
Trang 6đợc các cách biểu diễn khác nhau của tích này?
Cụ thể: Tích ABCD có 5 cách đặt ngoặc khác nhau:
Phân tích bài toán: Gọi số cách đặt ngoặc trong trờng hợp có n thừa số là T(n).
Bài toán trở thành tìm cách tính T(n) khi biết n Bài toán này cha cho trực tiếpcông thức truy toán
Ta cần phải xây dựng công thức truy toán tính T(n)
Nhận thấy trong các cách đặt ngoặc luôn tồn tại một cách đặt dấu ngoặc chia tích thành hai phần: phần trái có i thừa số, phần phải có n-i thừa số, với i = 1, 2, ,n-1 Có T(i) cách đặt ngoặc cho phần bên trái và T(n-i) cách đặt ngoặc cho phầnbên phải nên có công thức:
Ngoài ra với điều kiện ban đầu T(1)=1, chúng ta có thể tính đợc giá trị của T
nh trong bảng sau:
Các giá trị của T(n) đợc gọi là các số Catalan
Dựa vào công thức truy hồi (1) chúng ta tính T(n) bằng quy hoạch động Giá trịcác phần tử của mảng T đợc xây dựng dần từ 1 đến n:
)1()
()
()
i n T i T n
T
Trang 7Ví dụ 3: Tìm đờng đi ngắn nhất giữa các cặp hai đỉnh trên đồ thị n đỉnh,
có trọng số, không có chu trình âm (thuật toán Floyld).
Xây dựng mảng hai chiều A[1 N,1 N] với ý nghĩa giá trị cuối cùng tính
đợc của A[i,j] là độ dài đờng đi ngắn nhất từ đỉnh i tới đỉnh j Đồng thời dùngmảng G[1 N,1 N] với ý nghĩa G[i,j]=k nếu k là đỉnh trung gian mà đờng đi ngắnnhất từ i tới j phải qua k, đó là đỉnh thoả mãn: A[i,k]+A[k,j]<A[i,j]
Nh vậy mỗi khi tìm đợc đỉnh k, bài toán đã đợc phân rã thành hai bài toán
t-ơng tự là tìm đờng đi ngắn nhất từ i đến k và tìm đờng đi ngắn nhất từ k đến j
Ví dụ 4: Tìm đờng đi ngắn nhất từ đỉnh x đến đỉnh y trên đồ thị n đỉnh, có trọng số không âm (thuật toán Dijkstra).
) , , 2 ( )
( ).
( )
1
n i
j i T j T i
Trang 8áp dụng nguyên lý quy hoạch động của Bellman bằng kỹ thuật gán nhãn(xem chơng Đồ thị hữu hạn và các thuật toán cơ bản)
II Một số bài toán tiêu biểu:
Bài 1: (Dãy con không giảm dài nhất)
Cho N số nguyên dơng (0<N104) và một dãy A1, A2, ,An các số nguyên.Tìm trong dãy đã cho một dãy con
thoả mãn các điều kiện:
Hớng dẫn: Xây dựng mảng T và mảng D với ý nghĩa:
T[i]=j là chỉ số j (trong dãy (*)) của phần tử đứng ngay trớc Ai trong dãy kếtquả Cách tính T[i]: duyệt mảng A từ vị trí 1 đến vị trí i-1, tìm vị trí j có D[j] lớnnhất trong số các vị trí j thoả mãn A[j]A[i]
D[i] là độ dài của dãy kết quả khi bài toán chỉ xét dãy A1, A2, ,Ai và đợc tínhtheo công thức truy hồi:
D[i] = Max { D[j] +1 j mà j<i và AjAi }
Chú ý khởi trị: T[1]:= 0 ; D[1]:= 1; Ví dụ:
(*) ,
, , ,
3 2
A
j
j 1
Trang 9A[i] 6 12 8 11 3 4 1 7 5 9 10 2
Khi duyệt ngợc tìm kết quả ta tiến hành nh sau:
Tìm phần tử lớn nhất trong D, giả sử đó là D[i], ta đổi dấu của D[i] coi nh đánhdấu nó, tìm tiếp phần tử j = T[i], lại đổi dấu D[j], quá trình cứ nh thế lùi chỉ số j
type mang = array[1 max] of integer;
var a,d,t : mang;
Trang 10end;
function maxd: longint;
var i,p,li: longint;
begin
p := -maxint;
Trang 12Bài 2: (Dãy chung dài nhất của 2 dãy số)
Cho 2 số nguyên dơng M, N (0<M, N<=100) và 2 dãy số nguyên: A1, A2, ,
AN và B1, B2, ,B M Tìm một dãy dài nhất C nhận đợc từ A bằng cách xoá đi một
số số hạng và cũng nhận đợc từ B bằng cách xoá đi một số số hạng (nói chungkhông cùng chỉ số nh đối với dãy A) Ta gọi C là dãy con chung dài nhất của haidãy A và B
Dữ liệu vào: File BL2.INP có cấu trúc nh sau:
+ Dòng thứ nhất chứa N số A1, A2, ,AN
+ Dòng thứ hai chứa M số B1, B2, ,B M
Dữ liệu ra : File BL2.OUT có cấu trúc nh sau:
+ Dòng thứ nhất ghi số k là số số hạng của dãy C
+ Dòng thứ hai chứa k số là các số hạng của dãy C
+ Dòng thứ ba chứa k số là chỉ số trong dãy A của k số hạng của C
+ Dòng thứ t chứa k số là chỉ số trong dãy B của k số hạng của C
H
ớng dẫn:
Cần xây dựng mảng C[1 N,1 M] với ý nghĩa: C[i,j] là độ dài của dãychung dài nhất của hai dãy A[1 i] và B[1 j] Đơng nhiên C[1,j] = 0 nếu A[1]không có trong dãy B, ngợc lại thì C[1,j] = 1 Tơng tự C[i,1] = 0 nếu B[1] không
có trong dãy A, ngợc lại thì C[i,1] = 1 Những trờng hợp còn lại C[i,j] đợc tínhtheo công thức truy hồi sau:
C[i,j] = Max{C[i,j-1],C[i-1,j],C[i-1,j-1]+x}
Trang 13(mµ x=0 nÕu A[i] B[j] vµ x=1 nÕu A[i]=B[j])
Trang 15for j:=2 to n do
nh[i,j] := max(nh[i-1,j-1]+ord(a[i]=b[j]), nh[i,j-1],nh[i-1,j]);
writeln(f,'do dai 2 day sau khi xoa : ',nh[m,n]);
Trang 16thuc_hien;
close(f);
END.
Bài 3: (Di chuyển từ Tây sang Đông)
Cho hình chữ nhật MN ô vuông, mỗi ô chứa 1 số nguyên Có thể dichuyển từ 1 ô sang ô thuộc cột bên phải cùng dòng hoặc chênh lệch 1 dòng Tìmcách di chuyển từ một ô nào đó của cột 1 đến một ô nào đó thuộc cột n sao chotổng các số của các ô đi qua là nhỏ nhất
Dữ liệu vào lấy từ file ‘BL3.INP’ dòng đầu là 2 số nguyên dơng M, N Mdòng tiếp theo mỗi dòng N số nguyên của hình chữ nhật
Kết quả ghi ra file ‘BL3.OUT’ gồm 2 dòng:
Dòng thứ nhất ghi tổng các số của các ô đi qua
Dòng thứ hai ghi N số là chỉ số dòng của các ô đi qua từ cột 1 đến cột N
Nhãn của các ô thuộc cột 1 bằng chính giá trị các ô đó Các ô còn lại, lần lợt từ cột
2 đến cột n đợc xây dựng theo công thức truy hồi sau:
F[i,k] := Min { F[i-1,k-1], F[i,k-1], F[i+1,k-1] } + A[i,k]
Ngoài ra, dùng mảng hai chiều T[1 M,1 N] để ghi lại chỉ số dòng của ôthuộc cột j-1 đi tới ô (i,j) và mảng một chiều KQ[1 N] để ghi lại chỉ số dòng củacác ô đi qua từ cột 1 đến cột n trong phơng án tối u
Cũng lu ý rằng có thể không cần dùng mảng F[1 M,1 N] bằng cách ghigiá trị của F[1 M,1 N] đè dần lên mảng A[1 M,1 N] bắt đầu từ cột 2 đến cộtN
uses crt;
const maxmn = 100;
fi = 'BL3.INP';
fo = 'BL3.OUT';
Trang 17var a,t : array[0 maxmn,0 maxmn] of integer;
function min(i,j : byte): byte;
var p : integer; d : byte;
Trang 19Bài 4a: (Xếp va li)
Cho một va ly có thể chứa W đơn vị trọng lợng Có N loại đồ vật (số lợng mỗi
đồ vật không hạn chế), đồ vật i có trọng lợng A[i] và có giá trị là C[i] Hỏi nênchọn mỗi loại đồ vật bao nhiêu xếp vào va ly để tổng giá trị của va ly là lớn nhất
Dữ liệu vào lấy từ file văn bản ‘VALY.INP’ gồm ba dòng
Dòng thứ nhất là N và W
N dòng tiếp theo: dòng i+1 ghi hai số: A[i] và C[i] (i=1,2, N), hai số cách nhau bởi dấu cách
Kết quả ghi ra file văn bản ‘VALY.OUT’ theo quy cách sau:
Dòng thứ nhất là tổng giá trị lớn nhất của va ly
Trang 20 Các dòng tiếp theo mỗi dòng 2 số: số i (số hiệu vật đợc chọn) và số x (số lợng
chọn vật i)
Trang 212 1
3 1
Trang 22 Hai mảng một chiều v1 và v2: v1[y] là số hiệu đồ vật đợc chọn cuối cùngkhi trọng lợng còn thiếu của va ly là y và vừa xét xong vật có số hiệu lẻ,v2[y] là số hiệu đồ vật đợc chọn cuối cùng khi trọng lợng còn thiếu của va
ly là y và vừa xét xong vật có số hiệu chẵn
b) Thực hiện: Để diễn đạt khi không phân biệt g1, g2 ta tạm dùng ký hiệu g,không phân biệt v1, v2 ta dùng ký hiệu v
Khởi trị g[0]=0,v[0]=0, g1[i] bằng giá trị nhận đợc khi chọn một lợng tối đa
đồ vật 1 cho vào va ly có trọng lợng còn thiếu là i (lu ý số hiệu đồ vật 1 làk=1 là số lẻ); v1[i]=1 nếu chọn đợc ít nhất một đồ vật 1 cho vào va ly cótrọng lợng còn thiếu là i
Sau đó xét chọn tiếp các đồ vật từ số hiệu k=2 đến n cho vào va ly còn thiếutrọng lợng y nếu thấy lợi theo công thức gán nhãn sau:
Tìm kết quả: nếu N chẵn thì lần ngợc theo g2 và v2, nếu N lẻ theo g1 và v1.Kết quả số hiệu các đồ vật cho vào va ly đợc ghi nhận vào mảng một chiềux: với ý nghĩa x[j] là số lợng đồ vật có số hiệu j đợc chọn vào va ly
g k a y g k c
y k a khi
y g y g
][)][1,]]
[[2][max(
][
][1][2
][2][1
][1][2
y g y g k
y g y g khi y
v y v
][2][1
][2][1
y g y g k
y g y g khi y
v y v
g k a y g k c
y k a khi y
g y g
][)][2,]]
[[1][max(
][]
[2][1
Trang 23Ghi chú: Tuy nhiên bài toán này còn có thể giải bằng thuật toán có hiệu quả hơn
về thời gian thực hiện cũng nh kích thớc bộ nhớ so với thuật toán vừa nêu (xem
sum_max : longint; {Tổng giá trị chọn đợc}
g1,g2:array[0 1500] of integer; {Theo rõi tổng giá trị chọn}
v1,v2:array[0 10000] of integer; {Số hiệu vật chọn}
Trang 24procedure tinh1(k,y:integer);{k =3,5,7 -> t¹o g1 tõ g2, v1 tõ v2}
begin {qu¸ tr×nh t¬ng tù thñ tôc trªn}
if a[k]>y then g1[y]:=g2[y]
else
g1[y]:=max(g2[y],c[k]+g1[y-a[k]]);
if g2[y]=g1[y] then v1[y]:=v2[y];
if g2[y]<g1[y] then v1[y]:=k;
Trang 25if (k mod 2)=0 then
for y:=1 to w do tinh2(k,y)
{Khi va ly cßn thiÕu träng lîng y, xÐt chän vËt k ch½n, x©y dùng g2,v2}
else
for y:=1 to w do tinh1(k,y);
{Khi va ly cßn thiÕu träng lîng y, xÐt chän vËt k lÎ, x©y dùng g1,v1}
Trang 26Cách nghĩ theo phơng pháp này nh sau: Giá trị va ly trong cách xếp tốt nhất
có trọng lợng tối đa là K coi nh tổng giá trị của 2 va ly trong cách xếp tốt nhất cótrọng lợng tối đa là i và K-i (i nhận giá trị từ (K div 2) đến K)
Khi va ly thứ hai có trọng lợng là 0 thì ta hiểu là không thể phân chia va lythứ nhất đợc nữa, hay nói cách khác lúc đó va ly có trọng lợng tối đa bằng K chỉchứa 1 vật có giá trị tốt nhất mà trọng lợng vật này là K
Vậy bằng cách chia nhỏ dần các va ly ta sẽ tìm đợc các va ly không thể chianhỏ đợc nữa, đó chính là các va ly mà mỗi cái đựng 1 vật có giá trị tốt nhất bêntrong nó Tập hợp các va ly này chính là tập các vật cho vào va ly ban đầu trongphơng án tốt nhất
Về tổ chức dữ liệu và thực hiện:
Tạo mảng L với kích thớc bằng trọng lợng tối đa W L[K] cho giá trị tối ucủa va ly có trọng lợng không lớn hơn K Khởi trị L: tìm đồ vật i0 trong các đồ vật
có trọng lợng W0 , có giá trị tốt nhất, ghi nhận L[W0] := C[i0],
Đồng thời dùng mảng p1(W) để ghi nhận số hiệu của các đồ vật i0 nêu trên:p1[W0]=i0 Mảng p2(W) để ghi nhận đồ vật i0 không thể phân chia đợc nữa:p2[w0]=0 (sau đây ta sẽ dùng p1 và p2 với ý nghĩa khác nhng không mâu thuẫn với
ý nghĩa vừa trình bày)
Trong quá trình phân chia va ly, ta xây dựng nhãn của va ly có trọng l ợngtối đa là k theo công thức quy hoạch động sau:
Trang 27L[k] := Max { L[k], L[i] + L[k-i] k=1, n, i= (k div 2), ,k-1,k }
Khi thực hiện công thức trên đồng thời với xây dựng mảng L, ta cũng xâydựng mảng p1 và p2 : p1[k]:= i; p2[k] := k-i nghĩa là xác nhận nếu chọn phơng ántối u cho va ly có trọng lợng tối đa bằng k thì nó đợc phân chia thành 2 va ly, mộtcái có trọng lợng tối đa là i, cái kia có trọng lợng tối đa là k-i Nếu k-i=0 thì va lythứ nhất (trọng lợng tối đa là i) là phơng án tối u mà đã khởi trị ban đầu (rõ rànggiá trị mới của p1[i] là i không đợc ghi đè lên giá trị cũ của nó là số hiệu của va lytốt nhất có trọng lợng bằng i vì việc ghi đè này chỉ tiến hành sau khi va ly i có thểphân chia đợc thành 2 va ly cùng có trọng lợng khác 0)
Rõ ràng cách giải thứ hai nhiều thuận lợi hơn cách thứ nhất
Ch
ơng trình:
uses crt;
const mv = 2000; {max so loai do vat}
mw = 6000; {max trong luong}
Trang 29procedure timkq(k : integer);
var i,j : integer;
Trang 30Dữ liệu vào lấy từ file văn bản ‘VALY.INP’ gồm ba dòng
Dòng thứ nhất là N và W
N dòng tiếp theo: dòng i+1 ghi hai số số A[i] và C[i] (i=1,2, n), hai số cách nhau bởi dấu cách
Kết quả ghi ra file văn bản ‘VALY.OUT’ theo quy cách sau:
Dòng thứ nhất là tổng giá trị lớn nhất của các đồ vật đợc chọn
Các dòng tiếp theo mỗi dòng 3 số là số hiệu, trọng lợng, giá trị vật đợc chọn
2 5 300
3 5 300
b) Khởi trị L[0,j]=0; j: 0<j<=w, L[i,0]=0; i: 0<i<=N
c) Xây dựng nhãn L[i,j] theo công thức
Trang 31L[i,j] = Max(L[i-1,j], L[i-1,j-A[i]] + C[i]) nÕu A[i]j HoÆc L[i,j] = L[i-1,j] nÕu A[i]>j
Trang 34
doc_file;
xuly;
ghi_file;
END.
Bài 5: Biến đổi xâu:
Với một xâu ký tự S cho trớc, ta có thể thực hiện các phép biến đổi sau:
D: xoá một ký tự của xâu S Ký hiệu D i mà i là vị trí ký tự cần xoá
I: chèn trớc vị trí t của xâu S một ký tự c nào đó Ký hiệu I t c Quy định thêm
về vị trí chèn: nếu xâu S có độ dài K, vị trí chèn có thể là 1, 2, 3, , k+1 mà chèn ở
vị trí k+1 có nghĩa là viết thêm vào cuối xâu S
R: thay ký tự thứ t của S bởi ký tự c nào đó Ký hiệu R t c
Giả sử X và Y là hai xâu ký tự Độ dài xâu X là N, độ dài xâu Y là M Hãy tìm mộtdãy gồm ít nhất các phép biến đổi biến xâu X thành xâu Y
Số phép biến đổi ít nhất gọi là khoảng cách giữa hai xâu
Dữ liệu vào ghi trong file ‘QHD05.INP’ gồm hai dòng: Dòng thứ nhất là xâu X,dòng thứ hai là xâu Y
Kết quả ghi ra file ‘QHD05.OUT’:
+ Dòng thứ nhất là số K, đó là khoảng cách hai xâu
+ K dòng tiếp theo mỗi dòng ghi ký hiệu một phép biến đổi theo trình tự thực hiện đểbiến X thành Y
Ví dụ:
Trang 35ớng dẫn : Gọi L[i,j] là số lợng ít nhất các phép biến đổi (chèn, xoá, thay thế)
để biến xâu con x1x2 xj thành xâu con y1y2 yi
Nếu xj =yi thì L[i,j]=L[i-1,j-1] vì chỉ cần biến đổi x1x2 xj-1 thành y1y2 yi-1
thì x1x2 xj sẽ biến thành y1y2 yi
Nếu xj<>yi xét 3 khả năng biến đổi :
Xoá xj của X và biến đổi x1x2 xj-1 thành y1y2 yi, số biến đổi là L[i, j-1]+1
Biến đổi x1x2 xj thành y1y2 yi-1 rồi chèn yi vào X sau yi-1, số biến đổi là L[i-1,j]+1
Biến đổi x1x2 xj-1 thành y1y2 yi-1 rồi thay xj của X bởi yi, số biến đổi là L[i-1,j-1]+1
Công thức truy hồi chung cho trờng hợp xi<>yj là:
L[i,j] := min(L[i-1,j]+1,L[i,j-1]+1,L[i-1,j-1]+1)
Ngoài ra lu ý khởi trị mảng L[0 M,0 N] nh sau:
L[0,j]=j 0 j N vì phải xoá j ký tự của X để thành xâu rỗng Y
L[i,0]=i 0 i M vì phải chèn i ký tự của Y vào xâu rỗng X
Sau khi có bảng L[0 m,0 n] dùng nó để tìm ra các phép biến đổi
L[m,n] là số phép biến đổi cần tìm Điểm bắt đầu tìm kiếm là điểm (M,N)
Từ điểm (i,j) trong bảng ta tìm các điểm tiếp theo dựa vào nhận xét:
L[i,j]= L[i-1,j]+1 là dùng phép I (chèn)
L[i,j]= L[i,j-1]+1 là dùng phép D (xoá)
L[i,j]= L[i-1,j-1]+1 là dùng phép R (thay)
Trong quá trình tìm, ghi lu toạ độ (vị trí) của các điểm này vào hai mảng mộtchiều d và c để biết tại điểm tìm đợc ta đang xét vị trí nào trên X ban đầu và vị trínào trên Y
Trang 39D÷ liÖu vµo lÊy tõ file ‘QHD04.INP’ gåm:
dßng thø nhÊt lµ sè N
dßng thø hai lµ N+1 sè d0, d1, , dn
KÕt qu¶ ghi ra file ‘QHD04.OUT’ gåm:
Trang 40H
ớng dẫn : Ma trận là mảng hai chiều Phép nhân ma trận không giao hoán nhng
kết hợp: với 3 ma trận A, B, C nhân đợc với nhau ta có A(BC)=(AB)C Điều kiện
để có thể nhân ma trận A với ma trận B là số cột của A phải bằng số dòng của B.Nếu A có M dòng N cột và B có N dòng P cột thì ma trận tích C=AB có M dòng Pcột và phần tử dòng i cột j của C đợc tính bằng công thức:
Nh vậy, để nhân A với B ta cần thực hiện M.N.P phép nhân Khi chạy máy tính,thời gian thực hiện phép nhân lớn hơn phép cộng Do đó khi nhân nhiều ma trậnvới nhau nếu thu xếp khéo trình tự nhân, ta có thể giảm đáng kể số phép nhân
Khi tính tích M=M1.M2 MN trong đó Mi là các ma trận sao cho hai matrận liên tiếp trong tích có thể nhân với nhau Phép nhân ma trận có tính chất kếthợp, do vậy có nhiều cách thực hiện M=( ((M1.M2)M3) MN) hoặcM=(M1(M2(M3 (MN-1MN) ))) v v Ta có thể thấy với mỗi cách quy định cácdấu ngoặc, số phép nhân nói chung khác nhau
Ví dụ xét tích ABCD của 4 ma trận với kích thớc A(13,5), B(5,89), C(89,3),D(3,34) Để biết hiệu quả của các cách tính khác nhau chúng ta tính số lợng cácphép nhân đợc thực hiện trong mỗi cách Có 5 cách tính khác nhau:
((AB)C)D 10.582 số phép nhân phải thực hiện
Phơng pháp hiệu quả nhất coi nh nhanh hơn 19 lần so với cách chậm nhất
Có thể trực tiếp tìm ra cách tốt nhất bằng cách đặt các biểu thức trong ngoặc
đơn theo các kiểu có thể và tính số lần thực hiện các phép nhân Số các cách khácnhau để đặt ngoặc cho tích n ma trận là số Catalan T(N)
Nhận thấy T(N) tăng rất nhanh khi n tăng, T(1)=1, T(15) =2674440 nên
ph-ơng pháp tính trực tiếp này không có khả năng hiện thực khi N lớn
()
i
i N T i T N
j k B k i A j
i C
1
],[]
,[]
,[