Trong quá trình học tập, chúng ta gặp rất nhiều các bài tập về ToánTin. Các bài tập dạng này rất phong phú và đa dạng. Thực tế chưa có thuật toán hoàn chỉnh có thể áp dụng cho mọi bài toán. Tuy nhiên người ta đã tìm ra một số thuật toán chung như chia để trị, tham ăn, quay lui,... Các thuật toán này có thể áp dụng để giải một lớp khá rộng các bài toán hay gặp trong thực tế.
Trang 1TÀI LIỆU
THUẬT TOÁN
QUI HOẠCH ĐỘNG
Trang 2nhiên, s th t l khó ẽ ậ à để có th tìm ể đượ ơ ở à c c c v công th c cho vi c s ứ ệ ử
d ng qui ho ch ụ ạ độ ng Chính vì v n ấ đề à n y, qui hoach độ ng l i tr ạ ở
th nh không ph bi n à ổ ế Đố ớ i v i nh ng b i toán nh v y, chúng ta l i c ữ à ư ậ ạ ố
g ng i tìm cách gi i khác ví d nh vét c n hay tham lam i u ó ắ đ ả ụ ư ạ đ ề đ
th t l d ! Chính vì v y, tôi mu n ậ à ở ậ ố đư a ra m t s b i toán áp d ng qui ộ ố à ụ
ho ch ạ độ ng để mong r ng sau b i báo n y, các b n s yêu thích gi i ằ à à ạ ẽ ả thu t n y h n ậ à ơ
Tr ướ c h t các b n ph i luôn nh r ng, gi i thu t qui ho ch ế ạ ả ớ ằ ả ậ ạ độ ng đượ c
xu t phát t nguyên lí Bellman: n u 1 c u hình l t i u thì m i c u ấ ừ ế ấ à ố ư ọ ấ hình con c a nó c ng l t i u Chính vì v y ủ ũ à ố ư ậ để xây d ng 1 c u hình ự ấ
t i u, ta hãy xây d ng d n các c u hình con sao cho các c u hình con ố ư ự ầ ấ ấ
n y c ng ph i t i u ây chính l à ũ ả ố ư Đ à đườ ng l i ch ố ủ đạ o cho m i b i toán ọ à qui ho ch ạ độ ng Sau ây l m t s b i toán đ à ộ ố à đượ c gi i quy t b ng qui ả ế ằ
ho ch ạ độ ng.
I Các b i toán à
B i 1: Tr à ướ c tiên chúng ta hãy xét 1 b i toán th t à ậ đơ n gi n v quen thu c ả à ộ
ó l tìm giá tr l n nh t trong n s l a1, a2, , an Gi i quy t b i toán
Nh v y khi k ư ậ đạ ớ t t i n thì maxn chính l giá tr l n nh t trong n s ã à ị ớ ấ ố đ
ch Vi c c i ọ ệ à đặ t ch ươ ng trình h t s c ế ứ đơ n gi n nh sau: ả ư
Uses crt;
Var a: array[1 100] of integer;
n,k,max: integer;
Begin
Write('Cho so luong phan tu: ');readln(n);
For i:=1 to n do begin write('a[',i,']= ');readln(a[i]);end;
Max:=a[1];
For k:=2 to n do
Trang 3If a[k]>max then max:=a[k];
Write('Gia tri lon nhat cua day cac so da cho la: ',max);
Readln
End.
Bây gi chúng ta xét ờ đế n b i toán 2 có ph n h p d n h n ây chính l à ầ ấ ẫ ơ Đ à
m t trong nh ng b i toán i n hình cho gi i thu t qui ho ch ộ ữ à đ ể ả ậ ạ độ ng:
B i 2: B i toán cái túi: Cho n lo i à à ạ đồ ậ v t (1 n 100) v i m t ≤ ≤ ớ ộ đồ ậ v t lo i ạ
th i (1 i n) có tr ng l ứ ≤ ≤ ọ ượ ng l a[i] v giá tr s d ng l c[i] M t nh à à ị ử ụ à ộ à thám hi m c n mang theo m t s ể ầ ộ ố đồ ậ à v t v o túi c a mình sao cho t ng ủ ổ
tr ng l ọ ượ ng các đồ ậ đ v t em theo không v ượ t quá s c ch u ứ ị đự ng c a túi ủ
l w (1 w 250) v t ng giá tr s d ng t các à ≤ ≤ à ổ ị ử ụ ừ đồ ậ đ v t em theo l l n à ớ
nh t Hãy tìm m t ph ấ ộ ươ ng án mang cho nh thám hi m v i gi s r ng à ể ớ ả ử ằ
s l ố ượ ng đồ ậ ủ v t c a m i lo i l luôn ỗ ạ à đủ dùng.
* Thu t gi i b ng qui ho ch ậ ả ằ ạ độ ng đượ c mô t nh sau: ả ư
Ta xây d ng m t m ng 2 chi u f v i f[i,j] l giá tr s d ng l n nh t có ự ộ ả ề ớ à ị ử ụ ớ ấ
c b i j v t t 1 n j m t ng tr ng l ng không v t quá j.
Kh i t o : f[i,1]:=0 v i i < a[1] ở ạ ớ
F[i,1]:=c[1]*(i div a[1]) v i i > =a[1]; (i = 1 w); ớ
Ta l n l ầ ượ t cho i đạ ớ t t i w v j à đạ ớ t t i n b ng cách sau: ằ
For j:=2 to n do
For i:=1 to w do
If i >= a[i] then f[i,j]:=Max(f[i-a[j],j]+ c[j],f[i-1,j])
Else f[i,j]:=f[i-1,j].
Nh v y cho ư ậ đế n f[w,n] ta s thu ẽ đượ c giá tr l n nh t có th ị ớ ấ ể đạ đượ t c
t n lo i ừ ạ đồ ậ đ v t ã cho sao cho tr ng l ọ ượ ng không v ượ t quá w H th c ệ ứ toán trên đượ c g i l h th c Dantzig Có th r t d hi u ọ à ệ ứ ể ấ ễ ể đượ c thu t ậ toán nh sau: ư
Ph n xây d ng: chúng ta xét ầ ự đế n f[i,j] có ngh a l xét ĩ à đế n giá tr l n nh t ị ớ ấ
có th ể đạ đượ ừ t c t j lo i ạ đồ ậ v t (1,,j) m tr ng l à ọ ượ ng không qúa i V y ậ thì rõ r ng l n u i < a[j] thì có ngh a l à à ế ĩ à đồ ậ v t j không th mang i hay ể đ
v i tr ng l ớ ọ ượ ng l i thì ta v n không th c i thi n à ẫ ể ả ệ đượ c giá tr f v f v n ị à ẫ
nh n giá tr f[i,j-1] Ng ậ ị ượ ạ ế c l i n u i a[j] thì chúng ta xét vi c n u mang ≥ ệ ế thêm v t j thì s có l i h n vi c không mang hay không, i u ó có ngh a ậ ẽ ợ ơ ệ đ ề đ ĩ
l xét Max(f[i-a[j],j]+ c[j],f[i-1,j]) à
Ch ươ ng trình c i à đặ t gi i quy t b i toán cái túi r t ả ế à ấ đơ n gi n nh sau: ả ư Uses crt;
Trang 4Var value,weight:array[1 30]of 0 500;{value: gia tri;weight: trong luong} f:array[0 500,0 30] of 0 10000;
Trang 5II V n ấ đề công th c truy h i ứ ồ
i v i m t b i toán qui ho ch ng thì công th c truy h i c ng l m t
n y thì c ng không ph i quá khó b i t công th c qui ho ch à ũ ả ở ừ ứ ạ độ ng chúng
ta c ng có th suy ngay ra ũ ể đượ c công th c truy h ứ ồị
Tôi xin tr l i v i b i toán cái túi ã nêu trên ở ạ ớ à đ ở để xây d ng c u hình t i ự ấ ố
u cho b i toán cái túi có ngh a l ph i mang nh ng lo i v t n o v m i
N u f[i,k]=f[i,k-1] thì choose[i,k]:=choose[i,k-1] (do không mang v t k) ế ậ
N u không thì n choose[i,k]:=k (có ngh a mang theo v t k) ế ĩ ậ
Khi xây d ng ự đế n choose[w,n] thì ta ch c n chú ý ỉ ầ đế n c t cu i cùng c a ộ ố ủ
m ng choose v b t ả à ắ đầ u truy h i Gi s m ng number[i] (i=1 n) s cho ồ ả ử ả ẽ
ta s l ố ượ ng lo i v t i ạ ậ đượ c mang theo Ta s c i thi n ch ẽ ả ệ ươ ng trình gi i ả
b i toán cái túi trên nh sau: à ở ư
Trang 6for i:=1 to w do
begin
f[i,1]:=(i div weight[1])*value[1];
if i>=weight[1] then choose[i,1]:=1
write('* Gia tri cao nhat dat duoc la: ',f[w,sl]);writeln;
write('* Khoi luong da dung la: ',w-w1);writeln;writeln;
writeln('* Nha tham hiem can dem nhu sau: ');
Trang 7vì v y, th i gian ậ ờ để ự th c hi n ch ệ ươ ng trình b ng nhánh c n s r t lâ ằ ậ ẽ ấ ụ
R t ti c r ng, gi i thu t qui ho ch ấ ế ằ ả ậ ạ độ ng luôn luôn ch nêu ra ỉ đượ c m t ộ
c u hình t i u N u chúng ta gi i b ng qui ho ch ấ ố ư ế ả ằ ạ độ ng nh trên, th i ư ờ gian ch y ch ạ ươ ng trình r t nhanh chóng Ch ấ ươ ng trình trên ho n to n có à à
th c i thi n ể ả ệ đượ c b ng cách thay vì dùng m ng 2 chi u f v choose ta ằ ả ề à
có th ch dùng 4 m ng 1 chi u ó l f1, f2, choose1, choose2 b i th c ể ỉ ả ề đ à ở ự
ch t t i c t j c a f thì ta ch có th liên quan ấ ạ ộ ủ ỉ ể đế n c t j-1 c a f Chính vì ộ ủ
v y, 2 m ng f1,f2 có th dùng th l n l ậ ả ể ế ầ ượ t cho nhau t ươ ng đươ ng dùng
m ng 2 chi u f Khi ó ch ả ề đ ươ ng trình s có th ch y v i b d li u c ẽ ể ạ ớ ộ ữ ệ ỡ
- m i b ỗ ướ đ c i: xu ng 1 h ng t i s g n nh t bên trái hay ph i ố à ớ ố ầ ấ ả
* D li u: ữ ệ đọ ừ c t file 'va inp' có d ng: ọ ạ
- Dòng đầ u: s l ố ượ ng dòng c a tam giác ủ
- T dòng 2: các s c th ừ ố ụ ể
* Output: in ra m n hình à
- Hình tam giác cân đượ ạ ừ c t o t các s ố
- Giá tr t ng các s ã g p trên ị ổ ố đ ặ đườ ng i đ
- Các s ã g p trên ố đ ặ đườ ng i đ
( Câu 2 trong đề thi ch n ọ độ i tuy n Tin h c H N i 2001-2002) ể ọ à ộ
B i 4: Chúng ta hãy gi i quy t b i toán cái túi nh ng à ả ế à ư đượ c thay đổ đ i i
m t s chi ti t nh sau: M t nh thám hi m c n em theo m t s ộ ố ế ư ộ à ể ầ đ ộ ố đồ ậ v t
v o cái túi có tr ng t i không quá w c a ông Có t t c n à ọ ả ủ ấ ả đồ ậ v t, m i ỗ đồ
v t i có tr ng l ậ ọ ượ ng l a[i] v giá tr s d ng l c[i] Hãy giúp nh thám à à ị ử ụ à à
Trang 8hi m cách mang các ể đồ ậ v t sao cho t ng giá tr s d ng l l n nh t có ổ ị ử ụ à ớ ấ
th ể đượ c (m i ỗ đồ ậ v t ch có th mang 1 l n ho c không mang) ỉ ể ầ ặ
M t b i báo không th nói h t ộ à ể ế đượ ấ ả c t t c nh ng u vi t c a c m t ữ ư ệ ủ ả ộ thu t toán Tuy nhiên, sau b i báo n y, tôi hy v ng các b n s hay s ậ à à ọ ạ ẽ ử
d ng qui ho ch ụ ạ độ ng h n trong vi c gi i toán N u b n n o mu n l i ơ ệ ả ế ạ à ố ờ
gi i c th c a t t c các b i toán trên, hãy liên h v i tôi theo a ch : ả ụ ể ủ ấ ả à ệ ớ đị ỉ 44 Quy ho ch t i u m t b ng hai chi u - B i toán t ng quát ạ ố ư ộ ả ề à ổ 49
Có r t nhi u b i toán t i u trên m t b ng cho tr ấ ề à ố ư ộ ả ướ c g m M dòng, N c t ồ ộ
nh các d ng b i tìm m t h nh trình i t dòng th nh t t i dòng th M ư ạ à ộ à đ ừ ứ ấ ớ ứ tho mãn m t i u ki n t i u n o ó Nh ng c ng có nh ng b i toán ả ộ đ ề ệ ố ư à đ ư ũ ữ à
t i u v i s li u ban ố ư ớ ố ệ đầ à u l các m ng ph n t m t chi u ả ầ ử ộ ề đề u có th ể
a v b i toán quy ho ch t i u trên m t b ng hai chi u M t ví d d
th y v d g p nh t l b i toán tìm xâu con l n nh t, tìm o n dãy con ấ à ễ ặ ấ à à ớ ấ đ ạ
n i u d i nh t, b i toán cây x ng, v i n hình nh t l b i toán cái
túi (v i d li u ớ ữ ệ đầ u v o l nguyên) à à
T t c các b i toán ó chúng ta ấ ả à đ đề u có th ể đư ề ộ ạ a v m t d ng t ng quát ổ
m tôi t m g i l B i toán t ng quát quy ho ch t i u trên m t b ng hai à ạ ọ à ″ à ổ ạ ố ư ộ ả chi u B i vi t n y l s t ng h p c a b n thân tôi trong quá trình h c ề ″ à ế à à ự ổ ợ ủ ả ọ môn tin h c PASCAL Xin nêu ra ọ để các b n có th tham kh o v cho ạ ể ả à
L i u ki n b i toán à đ ề ệ à đư a ra Đườ ng i t i u đ ố ư đượ c tính b ng t ng ằ ổ
tr ng s các ô i qua Tr ng s c a m t ô ph thu c quy t c tính tr ng ọ ố đ ọ ố ủ ộ ụ ộ ắ ọ
- Tr ng s ph thu c v o ô ọ ố ụ ộ à đứ ng tr ướ c ô ang xét đ
3 Quy t c ắ ″Đ ừ i t trên xu ng d ố ướ ″ i :
T dòng th i b n có th i ngang sang trái ho c sang ph i trên dòng ó ừ ứ ạ ể đ ặ ả đ
v i xu ng d à đ ố ướ i dòng th (i+1) theo các h ứ ướ ng chéo ho c th ng ặ ẳ đứ ng Thu t gi i chung ậ ả
1 B ướ c 0: Mô hình hoá:
N u b i toán không ph i l d ng t i u trên m t b ng hai chi u, ta ph i ế à ả à ạ ố ư ộ ả ề ả tìm cách mô hình hoá để đư a nó v d ng n y ề ạ à
Trang 92 B ướ c 1: Xây d ng các quy t c tính tr ng s : ự ắ ọ ố
Xin l u ý r ng i u ki n t i u ây ã có s n ngay t ư ằ đ ề ệ ố ư ở đ đ ẵ ừ đầ u.
Tu theo d ng c a b i toán ta s có các quy t c tính tr ng s khác nhau ỳ ạ ủ à ẽ ắ ọ ố Khi i xem xét v i các b i toán c th ta s rõ h n i u n y đ ớ à ụ ể ẽ ơ đ ề à
3 B ướ c 2: Xây d ng quy t c i : ự ắ ″đ ″
ôi khi quy t c i ch a có s n m ph i t ng i l p trình t ra cho phù
h p v i cách mô hình hoá c a mình V n ợ ớ ủ ấ đề à n y thu c v o t duy c a ộ à ư ủ
m i ng ỗ ườ i nên r t phong phú v ph c t p ấ à ứ ạ
4 B ướ c 3: Xây d ng công th c t i u: ự ứ ố ư
ây l b c quan tr ng nh t c a b i toán xây d ng c công th c,
ta c n ph i d a v o các quy t c i v tính tr ng s ầ ả ự à ắ đ à ọ ố
5 B ướ c 4: Duy t ph ệ ươ ng án t i u: ố ư
ây l b c cu i cùng ghi d li u tìm c ra FILE k t qu
V i nh ng b i toán v i d li u ớ ữ à ớ ữ ệ đầ u v o l các m ng m t chi u thì ta s à à ả ộ ề ẽ dùng ngay các d li u ó m không c n xây d ng m ng A ữ ệ đ à ầ ự ả
Các b i toán quen thu c nh b i toán cái túi,b i toán tìm o n dãy con à ộ ư à à đ ạ
n i u d i nh t,b i toán cây x ng,.v v ta s không xét … n ây
nh trên sân ng v i m t dòng c a b ng ch nh t ho c i theo trên m t ỏ ứ ớ ộ ủ ả ữ ậ ặ đ ộ
c t c a sân Hãy ch ra ộ ủ ỉ đườ ng i giúp con ki n có đ ế đượ c nhi u th c n ề ứ ă
Trang 10(1,1) (2,1) (2,2) (2,3) (3,3)
Thu t gi i ậ ả
- B ướ c 0: B qua vì ây l b i toán úng d ng ỏ đ à à đ ạ
- B ướ c 1: Tr ng s ây l l ọ ố ở đ à ượ ng th c n trên m i ô ứ ă ỗ
- B ướ c 2: Quy t c i: ắ đ
B ướ c 3: Công th c quy ho ch ứ ạ
B[i,j] l l à ượ ng th c n l n nh t i t ô (1,1) ứ ă ớ ấ đ ừ đế n ô (i,j)
B[1,j] = A[1,j] v i j = 1 N ớ
B[i,1] = A[i,1]+B[i-1,1] v i i = 2 M ớ
B[i,j] =Max{B[i-1,j],B[i,j-1]} + A[i,j] v i i = 2 M v j = 2 N ớ à
2 B i toán Sa m c : à ″ ạ ″
M t bãi sa m c có d ng hình ch nh t MxN M i ô vuông ộ ạ ạ ữ ậ ỗ đơ n v trên sa ị
m c có m t ạ ộ độ cao n o ó M t ng à đ ộ ườ i mu n i t b ố đ ừ ờ đầ u n y sang b à ờ
cu i cùng bên kia Ng ố ườ đ i ó ch có th i t ô ang ỉ ể đ ừ đ đứ ng t i m t ô m i ớ ộ ớ theo h ướ ng th ng ẳ đứ ng chéo trái ho c chéo ph i Gi thi t r ng ng ặ ả ả ế ằ ườ đ i ó không đượ c v ượ t ra hai mép trái v ph i c a sa m c à ả ủ ạ
Hãy tìm đườ ng i sao cho ng đ ườ đ i ó ph i v ả ượ t qua quãng đườ ng ng n ắ
nh t M i l n i t m t ô sang ô m i ti p theo ng ấ ỗ ầ đ ừ ộ ớ ế ườ đ i ó ph i i h t ả đ ế quãng đườ ng b ng ằ độ chênh cao gi a hai ô ó ữ đ
SAMAC.INP
SAMAC.OUT
12 (Quãng đườ ng Min)
(1,3) (2,4) (3,3) (4,2) (5,2)
Thu t gi i -B ậ ả ướ c 0: B qua ỏ
- B ướ c 1: Tr ng s l ọ ố à độ chênh cao gi a hai ô liên ti p ữ ế
- B ướ c 2: Quy t c i ắ đ
- B ướ c 3: Công th c t i u: ứ ố ư
B[i,j] l quãng à đườ ng nh nh t i t b ỏ ấ đ ừ ờ đầ u tiên đế n ô (i,j)
B[1,j] = 0 v i j = 1 N ớ
B[i,1] = Min { B[i-1,1] + abs(A[i,1] - A[i-1,1]);
B[i-1,2] + abs(A[i,1] - A[i-1,2])}
V i i = 2 M ớ
B[i,j] = Min { B[i-1,j -1] + abs(A[i,j] - A[i-1,j -1]);
B[i-1,j] + abs(A[i,j] - A[i-1,j]);
B[i-1,j+1] + abs(A[i,j] - A[i-1,j+1])}
Trang 11V i i = 2 M, j = 2 N-1 ớ
B[i,N] = Min { B[i-1,N] + abs(A[i,N] - A[i-1,N]);
B[i-1,N-1] + abs(A[i,N] - A[i-1,N-1])}
V i i = 2 M ớ
3 B i toán Qu y bán h ng : à ″ ầ à ″
M t siêu th có M gian h ng, m i gian h ng g m N ng n ch a, m i ng n ộ ị à ỗ à ồ ă ứ ỗ ă
ch a ứ đượ c b trí m i phòng Giám ố ở ỗ đố c siêu th quy t nh m m t ị ế đị ở ộ
t khuy n mãi cho khách h ng v i các quy t c sau:
M i gian h ng ỗ à đượ c b trí trên t ng t ng t ố ừ ấ ươ ng ng t t ng 1 ứ ừ ầ đế n M
M i t ng có N thang máy i lên ng v i m i phòng ỗ ầ đ ứ ớ ỗ
M t khách h ng có th mua s n ph m t i m t gian h ng nh ng ch có ộ à ể ả ẩ ạ ộ à ư ỉ
th i theo m t h ể đ ộ ướ ng (không đượ c mua xong r i quay tr l i n i ã ồ ở ạ ơ đ mua)
Khách h ng có th i thang máy lên t ng ti p theo, nh ng ph i mua ít à ể đ ầ ế ư ả
nh t t i m t ng n ch a t ng ó thì m i ấ ạ ộ ă ứ ở ầ đ ớ đượ c phép i lên t ng trên đ ầ
n a ữ
Khách h ng mua h ng t i m t ng n ch a M i ng n ch a quy nh m t à à ạ ộ ă ứ ỗ ă ứ đị ộ
s l ố ượ ng h ng m ng à à ườ i khách bu c ph i mua khi ộ ả đế n ng n ch a ó ă ứ đ
N u ế độ chênh s l ố ượ ng h ng gi a hai ng n ch a liên ti p c a m t khách à ữ ă ứ ế ủ ộ
h ng l m t s may m n ã bi t tr à à ộ ố ắ đ ế ướ c Khách h ng ó s à đ ẽ đượ c khuy n ế mãi thêm m t s h ng b ng chính s may m n ó ộ ố à ằ ố ắ đ
n t ng th M, khách h ng ch có th mua h ng t i duy nh t m t ng n
ch a ứ
Hãy giúp khách h ng l a ch n i m xu t phát v h à ự ọ đ ể ấ à ướ ng i sao cho mua đ
c nhi u h ng nh t (K c s h ng c khuy n mãi)
D li u ữ ệ đầ u v o cho trong FILE v n b n SHOP.INP có c u trúc nh sau: à ă ả ấ ư Dòng đầ à u l 3 s M, N, K (1<M, N, K 100), K l s các con s may ố ≤ à ố ố
m n ắ
Dòng th hai ghi K con s may m n ứ ố ắ
M dòng ti p theo ghi s l ế ố ượ ng h ng quy nh t i m i ng n ch a M i à đị ạ ỗ ă ứ ỗ dòng g m N s cách nhau b i ít nh t m t d u tr ng ồ ố ở ấ ộ ấ ắ
K t qu ghi ra FILE v n b n SHOP.OUT nh sau: ế ả ă ả ư
Dòng m t l s l ộ à ố ượ ng h ng nhi u nh t à ề ấ
- Dòng hai i m xu t phát v quá trình mua h ng M i ng n ch a i qua đ ể ấ à à ỗ ă ứ đ
c bi u di n theo d ng (x,y) trong ó (x,y) l v trí c a ng n ch a
Trang 12B ướ c 0: B i toán n y th c ch t l b i toán xâu con l n nh t Ta xây à à ự ấ à à ″ ớ ấ ″
d ng b ng B[i,j] l xâu con l n nh t gi a 2 xâu S1[1 i] v S[1 j].G i ll = ự ả à ớ ấ ữ à ọ length(S1), l =length(S)
Nh n xét th y r ng v i B[ll,i]=ll v i i = ll l thì ta có m t ph ậ ấ ằ ớ ớ ộ ươ ng án để tách t B ng ph ừ ằ ươ ng pháp duy t d a trên b ng l u tr ng thái qua quá ệ ự ả ư ạ trình quy ho ch, ta xét xem nh ng v trí còn l i trong xâu S (ch a thu c ạ ữ ị ạ ư ộ S1) có t o ra xâu S2 không N u tho mãn i u ki n n y thì b i toán ã ạ ế ả đ ề ệ à à đ
gi i quy t xong L u ý r ng b i toán luôn có l i gi i ả ế ư ằ à ờ ả
B ướ c 1: Tr ng s l 0 ho c 1 tu xem S1[i] khác ho c b ng S[j] ọ ố à ặ ỳ ặ ằ
B ướ c 2: Quy t c i: ắ đ
Trang 13b ng hai chi u ả ề đề u có th gi i quy t b ng cách quy ho ch liên t c trên 2 ể ả ế ằ ạ ụ
m ng m t chi u Sau m i b ả ộ ề ỗ ướ c quy ho ch ph i thay ạ ả đổ i 2 m ng n y sao ả à cho phù h p v i b ợ ớ ướ c quy ho ch ti p theo Cái khó c a b i toán có d ạ ế ủ à ữ
li u l n n y l vi c l u tr tr ng thái ệ ớ à à ệ ư ữ ạ để sau khi quy ho ch to n b ta ạ à ộ còn có th in ra file k t qu quá trình i c a ph ể ế ả ″ đ ″ ủ ươ ng án t i u ố ư
R t mong nh n ấ ậ đượ c nh ng ý ki n óng góp quý báu c a các b n ữ ế đ ủ ạ đọ c ISM M i th c m c xin g i cho tôi theo a ch : ọ ắ ắ ử đị ỉ 50 Thu t toán Dijkstra trên c u trúc Heap ậ ấ 58
1 Nh c l i thu t toán Dijkstra tìm ắ ạ ậ đườ ng i ng n nh t đ ắ ấ
B i toán: Cho à đồ ị th có h ướ ng v i tr ng s các cung (i,j) l C[i,j] không ớ ọ ố à
Trang 142 C u trúc Heap v m t s phép x lí trên Heap ấ à ộ ố ử
a) Mô t Heap: Heap ả đượ c mô t nh m t cây nh phân có c u trúc sao ả ư ộ ị ấ cho giá tr khoá m i nút không v ị ở ỗ ượ t quá giá tr khoá c a hai nút con c a ị ủ ủ
nó (suy ra giá tr khoá t i g c Heap l nh nh t) ị ạ ố à ỏ ấ
b) Hai phép x lí trên Heap ử
- Phép c p nh t Heap ậ ậ
V n ấ đề : Gi s nút v có giá tr khoá nh i, c n chuy n nút v ả ử ị ỏ đ ầ ể đế n v trí ị
m i trên Heap ớ để ả b o to n c u trúc Heap à ấ
+ Tìm đườ ng i t g c v phía lá, i qua các nút con có giá tr khoá nh đ ừ ố ề đ ị ỏ
h n trong hai nút con cho ơ đế n khi g p lá ặ
Trang 15+ Trên d c ọ đườ ng i y, kéo nút con lên v trí nút cha c a nó đ ấ ị ủ
Ví d trong hình v 2 n u b nút g c có khoá b ng 1, ta s kéo nút con ụ ẽ ế ỏ ố ằ ẽ lên v trí nút cha trên ị đườ ng i qua các nút có giá tr khoá l 1, 2, 6, 8 v đ ị à à Heap m i nh hình 3 ớ ư
3 Thu t toán Dijkstra t ch c trên c u trúc Heap (t m kí hi u l ậ ổ ứ ấ ạ ệ à
V y thu t toán Dijkstra t ch c trên Heap nh sau: ậ ậ ổ ứ ư
C p nh t nút 1 c a Heap (t ậ ậ ủ ươ ng ng v i nút s có giá tr khoá b ng 0) ứ ớ ị ằ Vòng l p cho ặ đế n khi Heap r ng (không còn nút n o) ỗ à
S a nhãn cho v v ghi nh n nh tr ử à ậ đỉ ướ c v l u à
Trên Heap, c p nh t l i nút t ậ ậ ạ ươ ng ng v i nh v ứ ớ đỉ
+ Các phép x lí Heap ã nêu (c p nh t Heap v lo i b g c Heap) c n ử đ ậ ậ à ạ ỏ ố ầ
th c hi n không quá 2.lgM phép so sánh (n u Heap có M nút) S M t i ự ệ ế ố ố
Trang 16+ K t lu n: Trên ế ậ đồ ị th nhi u nh ít cung thì Dijkstra_Heap l th c hi n ề đỉ à ự ệ
Trang 17c^[p^[u]] := x; {xác nh n tr ng s c a cung (u,v) l x} ậ ọ ố ủ à
dec(p^[u]); {chuy n v v trí c a nh k ti p theo c a u} ể ề ị ủ đỉ ề ế ủ
Trang 18var cha,con : integer;
{n u nhãn c a nút cha (có s hi u l cha) l n h n nhãn c a nút v thì ế ủ ố ệ à ớ ơ ủ đư a
d n nút v v phía g c t i v trí tho mãn i u ki n c a heap b ng cách: ầ ề ố ớ ị ả đ ề ệ ủ ằ kéo nút cha xu ng v trí c a nút con c a nó } ố ị ủ ủ
function lay: integer;
{l y kh i heap nh g c, vun l i heap ấ ỏ đỉ ố ạ để hai cây con h p th nh heap ợ à
Trang 19if d[v]<=d[h[c]] then break; { d ng khi nhãn v không v ừ ượ t quá nhãn hai nút con}
h[r] := h[c]; {chuy n nút có s hi u l con lên nút có s hi u l cha} ể ố ệ à ố ệ à sh[h[r]] := r; {xác nh n l i s hi u trong heap c a nút m i chuy n lên} ậ ạ ố ệ ủ ớ ể
if u=t then break; {t i ích thì d ng} ớ đ ừ
dx[u] := True; { ánh d u u đ ấ đượ ố đị c c nh nhãn}
for j:= p^[u]+1 to p^[ 1] do {j: ch s trong m ng ke, c a các nh k v i ư ỉ ố ả ủ đỉ ề ớ u}
Trang 20writeln(f,-1) {ghi k t qu : vô nghi m} ế ả ệ
gi i quy t b i toán n y ch n h n nh : a bi u th c s h c theo ký
pháp h u t v ti n t , ho c ậ ố à ề ố ặ đư ề ạ a v d ng cây bi u th c Tuy nhiên ể ứ … ở
ây tôi mu n a ra m t ph ng pháp gi i khác v i nh ng ph ng pháp
trên nh m m c ích ằ ụ đ để cho các b n ạ đọ c g n xa tham kh o thêm v ầ ả à
c ng r t mong nh n ũ ấ ậ đượ c ý ki n ph n h i c a b n ế ả ồ ủ ạ đọ c g n xa ầ
3 Bi u th c có ch a 2 phép toán '+, *' thì gtbt = gtbt(dãy tr ể ứ ứ ướ c d u c ng ấ ộ
u tiên)+ gtbt(dãy sau d u c ng u tiên)
function gtbt(s:string):real;
Trang 22Function Tail(s:string;c:char):string; { h m tr v chu i à ả ề ỗ đứ ng sau d u c ấ
case s[i] of ’-’: begin insert(’+’,s,i); inc(i); end;
’/’: begin insert(’*’,s,i); inc(i); end;
6 Bi u th c có ch a 4 phép toán trên v d u ngo c: ể ứ ứ à ấ ặ
Tr ướ c tiên ta i tìm d u ngo c óng đ ấ ặ đ đầ u tiên tính t trái sang ph i trong ừ ả
b i u th c N u t n t i thì ta lui v trái tìm d u ngo c m ể ứ ế ồ ạ ề ấ ặ ở đầ u tiên m à
ta g p (tính t d u ngo c óng ặ ừ ấ ặ đ đầ u tiên) Sau ó trích bi u th c con đ ể ứ trong kho ng trên ra tính giá tr c a bi u th c con ó (5) v ả ị ủ ể ứ đ à đư a giá tr ị
y v d ng chu i ghép v o úng v trí c a nó ban u trong bi u th c
m L p l i b ẹ ặ ạ ướ c 6 Ng ượ ạ ế c l i n u không t n t i d u ngo c óng thì ồ ạ ấ ặ đ
bi u th c ã cho l bi u th c không có ch a d u ngo c (5) ể ứ đ à ể ứ ứ ấ ặ
Function Numbertostr(r:real):string;
var s:string;
begin
Trang 23end;
Tinh_gia_tri_bieu_thuc_khong_co_ngoac:=Tinh_gia_tri_bieu_thuc_khong_ dau_ngoac(s);
end;
7.X lí l i c a bi u th c: ta ch c n s a l i chút ít các o n mã l nh ử ỗ ủ ể ứ ỉ ầ ử ạ đ ạ ệ trên thì ta s phát hi n ẽ ệ đượ ấ c t t các các l i m bi u th c ó có ch n h n ỗ à ể ứ đ ẵ ạ
nh : sai cú pháp, xu t hi n kí t l , chia cho 0… ư ấ ệ ự ạ
8 M r ng phép toán: v i ph ở ộ ớ ươ ng pháp nêu trên các b n d d ng b sung ạ ễ à ổ thêm m t s phép toán v o bi u th c nh : ^, log, Ln, sin, cos, ộ ố à ể ứ ư …
9 Tính bi u th c d i: ta có th dùng m ng ể ứ à ể ả để ư l u tr bi u th c thay vì ữ ể ứ chu i ỗ
Trong quá trình vi t b i có th có xu t hi n m t s sai sót Mong b n ế à ể ấ ệ ộ ố ạ
c thông c m v t kh c ph c (n u c) ho c liên h v i tác gi c a
b i vi t à ế để ổ b sung 66 Dijtra - thu t toán t t ậ ố để ả gi i các b i toán t i u à ố ư 68
K thu t tìm ki m nh phân gi i m t s b i toán t i u ỹ ậ ế ị ả ộ ố à ố ư 74
Có l ai trong chúng ta c ng bi t v thu t toán tìm ki m nh phân v s ẽ ũ ế ề ậ ế ị à ự
hi u qu c a nó S d ng k thu t tìm ki m t ệ ả ủ ử ụ ỹ ậ ế ươ ng t trong m t s b i ự ộ ố à toán ta c ng ũ đạ đượ t c k t qu r t kh quan Sau ây l m t s b i toán ế ả ấ ả đ à ộ ố à
nh v y ư ậ
I B i toán ví d à ụ
Thông tin v m ng giao thông g m n th nh ph cho b i m ng A kích ề ạ ồ à ố ở ả
Trang 24th ướ c n?n g m các ph n t aij l m t giá tr nguyên d ồ ầ ử à ộ ị ươ ng ch t i tr ng ỉ ả ọ
c a tuy n ủ ế đườ ng n i 2 th nh ph i,j N u aij =0 thì gi a i,j không có ố à ố ế ữ
B i toán à đượ c chuy n th nh vi c tìm giá tr k l n nh t thu c kmin kmax ể à ệ ị ớ ấ ộ sao cho m ng giao thông có "l trình t i thi u k" Khi ó ạ ộ ố ể đ đườ ng i t s đ ừ
n t tìm c chính l ng i có t i tr ng l n nh t c n tìm
Ta s d ng k thu t tìm ki m nh phân d a trên nh n xét: n u m ng có ử ụ ỹ ậ ế ị ự ậ ế ạ
"l trình t i thi u p" v k l giá tr l n nh t ộ ố ể à à ị ớ ấ để có "l trình t i thi u k" ộ ố ể thì k thu c p kmax Ng ộ ượ ạ c l i (n u m ng không có "l trình t i thi u ế ạ ộ ố ể p") thì k thu c kmin p 1 ộ −
Th t c Search th c hi n vi c tìm ki m nh phân có d ng nh sau: ủ ụ ự ệ ệ ế ị ạ ư
1 Xây d ng ự đồ ị th G(k) nh ã mô t trên ư đ ả ở
2 Dùng thu t toán DFS ậ để ể ki m tra xem có đườ ng i t s đ ừ đế n t không
N u có thì ế đặ t Ok l true, ng à ượ ạ c l i thì Ok l false à
Trang 25mang1 = array[1 max] of integer;
mang2 = array[1 max, 1 max] of LongInt; var
if a[i,j] > 0 then begin
if l > a[i,j] then l := a[i,j];
if r < a[i,j] then r := a[i,j];
end;
Trang 27d ng thu t toán DFS có ụ ậ độ ph c t p tính toán l O(n2) nên gi i thu t có ứ ạ à ả ậ
th i gian th c thi c C.O(n2) v i C < 32 ờ ự ỡ ớ
b Ta không c n ph i xây d ng G(k) m t cách t ầ ả ự ộ ườ ng minh (tính h n ẳ
Trang 28th nh ma tr n k ) m ch c n thay bi u th c ki m tra có c nh (i,j) không à ậ ề à ỉ ầ ể ứ ể ạ
b ng bi u th c aij k (trong th t c DFS) ằ ể ứ ≥ ủ ụ
c Giá tr t i u l m t trong các ph n t c a A Trong b i n y do aij l ị ố ư à ộ ầ ử ủ à à à
s nguyên nên ta xác nh ố đị đượ c kho ng tìm ki m l mi n nguyên ả ế à ề
kmin kmax v th c hi n vi c tìm ki m nh phân trên mi n ó à ự ệ ệ ế ị ề đ
N u aij l s th c không th k thu t tìm ki m nh phân không áp d ng ế à ố ự ể ĩ ậ ế ị ụ
c trên mi n th c [kmin, kmax] áp d ng c ta ph i s p x p
t ng d n các ph n t d ă ầ ầ ử ươ ng c a A (t i a có n2 ph n t ) r i th c hi n ủ ố đ ầ ử ồ ự ệ tìm ki m nh phân trên dãy t ng d n ó Khi ó th t c search c n thay ế ị ă ầ đ đ ủ ụ ầ i: l kh i t o b ng 1, r kh i t o b ng n2 v th t c check c g i v i
tham s l d[k]: check(d[k]) trong ó d dãy t ng d n ch a n2 ph n t c a ố à đ ă ầ ứ ầ ử ủ
A
C ng có th l m th khi aij l s nguyên, tuy nhiên s không hi u qu vì ũ ể à ế à ố ẽ ệ ả
s t n th i gian s p x p dãy v t n không gian l u tr dãy ã s p ẽ ố ờ ắ ế à ố ư ữ đ ắ
II M t s b i toán áp d ng ộ ố à ụ
1 B i toán 1 ( à đề thi HSGQG n m h c 1999-2000) ă ọ
Có n công nhân v n công vi c N u x p công nhân i n u l m vi c j thì à ệ ế ế ế à ệ
ph i tr ti n công l aij Hãy tìm m t cách x p m i ng ả ả ề à ộ ế ỗ ườ i m t vi c sao ộ ệ cho ti n công l n nh t c n tr trong cách x p vi c ó l nh nh t ề ớ ấ ầ ả ế ệ đ à ỏ ấ
Thu t gi i ậ ả
N u b i toán yêu c u l tìm cách x p vi c sao cho t ng ti n công ph i ế à ầ à ế ệ ổ ề ả
tr l nh nh t thì ó l b i toán tìm c p ghép ả à ỏ ấ đ à à ặ đầ đủ ọ y tr ng s c c ố ự
ti u Tuy nhiên b i n y l tìm cách x p vi c sao cho ti n công l n nh t ể à à à ế ệ ề ớ ấ
l nh nh t Ta có ý t à ỏ ấ ưở ng nh sau: tìm s k bé nh t sao cho t n t i m t ư ố ấ ồ ạ ộ cách s p x p ắ ế đủ n ng ườ i, n vi c v các yêu c u v ti n công ệ à ầ ề ề đề u k ≤
D th y vi c tìm ki m ó có th th c hi n b ng k thu t tìm ki m nh ễ ấ ệ ế đ ể ự ệ ằ ĩ ậ ế ị phân, v vi c ki m tra s k có tho mãn không chính l vi c ki m tra à ệ ể ố ả à ệ ể đồ
th 2 phía G(k) có b ghép ị ộ đầ đủ y hay không Đồ ị đồ ị th th 2 phía G(k)
c xác nh nh sau:
G(k) = (X,Y,E) Trong ó: X l t p n nh ng v i n công nhân, Y l t p n đ à ậ đỉ ứ ớ à ậ
nh ng v i n công vi c V i i thu c X, j thu c Y n u aij k thì cho (i,j) ≥
Có n công nhân v n công vi c N u x p công nhân i n u l m vi c j thì à ệ ế ế ế à ệ
th i gian ho n th nh l Tij Hãy tìm m t cách x p m i ng ờ à à à ộ ế ỗ ườ i m t vi c ộ ệ sao t t c các công vi c ho n th nh trong th i gian s m nh t (các công ấ ả ệ à à ờ ớ ấ
vi c ệ đượ c ti n h nh song song) ế à
B i toán 3 N ng su t dây truy n à ă ấ ề
Trang 29Dây truy n s n xu t có n v trí v n công nhân ( ề ả ấ ị à đề đượ đ u c ánh s t ố ừ 1 n) aij l n ng su t (s s n ph m s n xu t à ă ấ ố ả ẩ ả ấ đượ c trong m t ộ đơ n v th i ị ờ gian) c a công nhân i khi l m vi c t i v trí j V i m i cách b trí dây ủ à ệ ạ ị ớ ỗ ố truy n (công nhân n o l m v trí n o) n ng su t c a m t v trí l n ng ề à à ở ị à ă ấ ủ ộ ị à ă
su t c a công nhân l m vi c t i v trí ó N ng su t chung c a dây ấ ủ à ệ ạ ị đ ă ấ ủ
truy n l n ng su t c a v trí kém nh t trên dây truy n Hãy tìm cách b ề à ă ấ ủ ị ấ ề ố trí dây truy n ề để có n ng su t cao nh t ă ấ ấ
ng ượ ạ c l i thì ph i ả đế ấ n l y h ng c a h ng có kho g n nh t Hãy ch n à ở ử à ầ ấ ọ
k c a h ng ử à để đặ t kho sao cho quãng đườ ng i l y h ng d i nh t trong đ ấ à à ấ
s các các c a h ng còn l i l ng n nh t ố ử à ạ à ắ ấ
Thu t gi i ậ ả
B i n y có th l m b ng vét c n (duy t các t h p) Ngo i ra còn có à à ể à ằ ạ ệ ổ ợ à
ph ươ ng pháp quy ho ch ạ độ ng Tuy nhiên chúng ho n to n không hi u à à ệ
qu khi n l n Ta có th áp d ng k thu t tìm ki m nh phân k t h p ả ớ ể ụ ỹ ậ ế ị ế ợ tham lam nh sau ư
Th t c search tìm ki m nh phân giá tr d trong mi n dmin dmax t ủ ụ ế ị ị ề ươ ng
t b i toán 1 Riêng th t c check(d) s th c hi n khác Thay vì ki m tra ự à ủ ụ ẽ ự ệ ể xem có th b trí k kho sao cho quãng ể ố đườ ng i l y h ng c a m i c a đ ấ à ủ ọ ử
h ng không có kho à đề u d không, ta s l m ng ≤ ẽ à ượ ạ ầ ượ ố c l i: l n l t b trí các kho sao cho quãng đườ ng i l y h ng c a m i c a h ng không bao đ ấ à ủ ỗ ử à
gi v ờ ượ t quá d
Cách l m nh sau: à ư
G i dij l kho ng cách gi a 2 c a h ng i,j: dij = |pi pj| ọ à ả ữ ử à −
Dùng 2 c a h ng gi có ch s l 0 v t = n+1 l m biên sao cho di0 = dit = ử à ả ỉ ố à à à
v i m i i t 2 kho (gi ) t i 2 c a h ng ó
V i m i c a h ng i t 1 ớ ỗ ử à ừ đế n n: n u i ã có kho thì chuy n sang c a ế đ ể ử
h ng ti p theo, ng à ế ượ ạ c l i thì:
1 Tìm c a h ng x có kho g n i nh t v phía bên trái (x thu c 0 i) ử à ầ ấ ề ộ
2 Tìm c a h ng y có kho g n i nh t v phía bên ph i (y thu c i t) ử à ầ ấ ề ả ộ
N u dix ho c diy d thì quãng ế ặ ≤ đườ ng i l y h ng c a i d (tho mãn) đ ấ à ủ ≤ ả
Ng ượ ạ c l i tìm c a h ng j ch a có kho xa i nh t v phía ph i (j thu c i y) ử à ư ấ ề ả ộ
Trang 30khách s n v m i xe bus s i qua m t s khách s n n o ó Xe bus i có ạ à ỗ ẽ đ ộ ố ạ à đ q[i] ch ng i Hãy s p x p h nh khách lên xe bus sao cho: ỗ ồ ắ ế à
1 M i xe bus không ch a nhi u h nh khách h n s gh c a nó ỗ ứ ề à ơ ố ế ủ
2 T t c h nh khách ấ ả à đề u lên xe bus có i qua khách s n mình c n đ ạ ầ đế n
3 S xe bus c n dùng l ít nh t ố ầ à ấ
Thu t gi i ậ ả
B i n y có m t thu t gi i áp d ng k thu t tìm ki m nh phân nh sau: ta à à ộ ậ ả ụ ĩ ậ ế ị ư
s tìm s T nh nh t sao cho: ch dùng T xe bus l ch ẽ ố ỏ ấ ỉ à ở đượ c h t khách ế tho mãn 3 i u ki n trên ả đ ề ệ
T s ẽ đượ c tìm b ng ph ằ ươ ng pháp nh phân trong mi n t 1 ị ề ừ đế n K Để
ki m tra giá tr T có tho mãn không, ta s tìm m t t h p T xe bus trong ể ị ả ẽ ộ ổ ợ
s K xe bus sao cho có th s p x p N h nh khách lên T xe bus ó tho ố ể ắ ế à đ ả mãn 3 i u ki n trên đ ề ệ
Ta ch n T xe bus b ng ph ọ ằ ươ ng pháp duy t t h p v ki m tra t h p có ệ ổ ợ à ể ổ ợ
c có tho mãn không b ng thu t toán c p ghép (ho c lu ng trên
th 2 phía) Thu t toán lu ng th c thi nhanh h n, ị ậ ồ ự ơ đượ c mô t nh sau: ả ư
1 Xây d ng ự đồ ị th 2 phía G(X,Y,E) Trong ó: X l các khách s n, Y l đ à ạ à các xe bus đượ c ch n (T xe bus) Kh n ng thông qua c a m i nh thu c ọ ả ă ủ ỗ đỉ ộ
X l s h nh khách à ố à đế n khách s n ó Kh n ng thông qua c a m i nh ạ đ ả ă ủ ỗ đỉ thu c Y l s ch ng i c a xe bus ó N u xe bus j i qua khách s n i thì ộ à ố ỗ ồ ủ đ ế đ ạ
t kh n ng thông qua trên c nh (i,j) l N, ng c l i thì t b ng 0
2 Tìm lu ng c c ồ ự đạ i trên đồ ị th G N u giá tr lu ng qua m i nh X ế ị ồ ỗ đỉ ở
b ng kh n ng thông qua c a nó thì vi c l a ch n t h p T xe bus ó l ằ ả ă ủ ệ ự ọ ổ ợ đ à tho mãn yêu c u T giá tr lu ng ta c ng d d ng tìm ả ầ ừ ị ồ ũ ễ à đượ c cách s p ắ
ph ươ ng pháp tìm ki m nh phân, n u ã duy t xong giá tr T thì ta không ế ị ế đ ệ ị
c n ph i ki m tra các t h p nhi u h n T ph n t (n u T tho mãn) ho c ầ ả ể ổ ợ ề ơ ầ ử ế ả ặ
ít h n T ph n t (n u T không tho mãn) ơ ầ ử ế ả
2 Ta ch c n tìm m t t h p tho mãn, nên s t h p c n duy t còn ít ỉ ầ ộ ổ ợ ả ố ổ ợ ầ ệ
Trang 31h n n a (tìm th y m t t h p tho mãn thì không c n tìm các t h p ơ ữ ấ ộ ổ ợ ả ầ ổ ợ khác cùng s ph n t n a) V ta có th áp d ng m t s k thu t tham ố ầ ử ữ à ể ụ ộ ố ĩ ậ lam trong khi duy t nh : u tiên ch n các xe bus ch ệ ư ư ọ ở đượ c nhi u khách, ề
i qua nhi u khách s n, không xét các xe bus không i qua khách s n n o
trong s các khách s n có h nh khách c n ố ạ à ầ đế n …
3 C n gi m mi n tìm ki m kmin kmax xu ng c ng nhi u c ng t t (k t ầ ả ề ế … ố à ề à ố ế
h p v i ph ợ ớ ươ ng pháp tham lam ch ng h n) M t khác ghi nh n l i nh ng ẳ ạ ặ ậ ạ ữ giá tr T ã xét ị đ để tránh ph i xét l i m t cách vô ích ả ạ ộ
Ta c ng có m t b i toán gi i b ng k thu t t ũ ộ à ả ằ ĩ ậ ươ ng t : ự
B i toán 6 M ng máy tính à ạ
M ng g m N máy tính, m t s c p máy ạ ồ ộ ố ặ đượ c n i v i nhau b ng cáp Có ố ớ ằ
m t ch ộ ươ ng trình i u khi n, máy n o đ ề ể à đượ à đặ c c i t ch ươ ng trình ó đ thì có th i u khi n t t c các máy khác có cáp n i tr c ti p v i nó (t t ể đ ề ể ấ ả ố ự ế ớ ấ nhiên có th i u khi n chính nó) C n ch n ra m t s ít máy nh t ể đ ề ể ầ ọ ộ ố ấ để
c i ch à ươ ng trình sao t t c các máy ấ ả đề đượ đ ề u c i u khi n ể
Thu t gi i ậ ả
B i n y ch gi i à à ỉ ả đượ c b ng cách duy t t t c các t h p Tuy nhiên áp ằ ệ ấ ả ổ ợ
d ng ph ụ ươ ng pháp tìm ki m nh phân s giúp gi m s t h p c n duy t ế ị ẽ ả ố ổ ợ ầ ệ
r t nhi u (l p lu n nh b i 5) B n ấ ề ậ ậ ư à ạ đọ c có th c i theo c 2 ph ể à ả ươ ng pháp để so sánh
Trên ây l m t s b i toán áp d ng đ à ộ ố à ụ đượ c k thu t tìm ki m nh phân ỹ ậ ế ị
L i gi i không kèm ch ờ ả ươ ng trình m u m d nh cho b n ẫ à à ạ đọ ự à đặ c t c i t
v a ừ để tránh b i vi t d i m t cách không c n thi t v a à ế à ộ ầ ế ừ để ạ đọ b n c rèn luy n k n ng l p trình B n ệ ỹ ă ậ ạ đọ c n o có nhu c u v ch à ầ ề ươ ng trình m u ẫ tham kh o, xin liên h v i tác gi qua email: TungNT31@yahoo.com
75
ph c t p thu t toán v t ch c d li u
Độ ự ạ ậ à ổ ứ ữ ệ 81 Qui ho ch ạ độ ng v i các b i toán có d li u l n ớ à ữ ệ ớ 90 Duy t v i ệ ớ độ ư u tiên v duy t v i à ệ ớ độ sâu h n ch ạ ế 100 Cách nhìn khác đố ớ i v i m t s l p b i toán quen thu c ộ ố ớ à ộ 116 Quan h sinh d li u v ti p c n Quy ho ch ệ ữ ệ à ế ậ ạ độ 120 ng Thu t toán quy ho ch ậ ạ độ 151 ng
H i thi Tin h c tr không chuyên to n qu c ộ ọ ẻ à ố 164 Các k thi Tin h c trên th gi i ỳ ọ ế ớ 170
Trang 32Thuật toán qui hoạch động
Bá Hiệp
Trong quá trình học tập, chúng ta gặp rất nhiều các bài tập về Toán-Tin Các bài tập dạng này rất phong phú và đa dạng Thực tế chưa có thuật toán hoàn chỉnh có thể áp dụng cho mọi bài toán Tuy nhiên người ta đã tìm ra một số thuật toán chung như chia để trị, tham
ăn, quay lui, Các thuật toán này có thể áp dụng để giải một lớp khá rộng các bài toán hay gặp trong thực tế Trong bài viết này, tôi muốn đề cập với các bạn một thuật toán khác, đó là thuật toán quy hoạch động Tư tưởng cơ bản của thuật toán là:
Để giải một bài toán ta chia bài toán đó thành các bài toán nhỏ hơn có thể giải một cách
dễ dàng Sau đó kết hợp lời giải các bài toán con, ta có được lời giải bài toán ban đầu Trong quá trình giải các bài toán con đôi khi ta gặp rất nhiều kết quả trùng lặp của các bài toán con Để tăng tính hiệu quả, thay vì phải tính lại các kết quả đó, ta lưu chúng vào một bảng Khi cần lời giải của một bài toán con nào đó ta chỉ cần tim trong bảng, không cần tính lại
Tư tưởng của thuật toán quy hoạch động khá đơn giản Tuy nhiên khi áp dụng thuật toán
vào trường hợp cụ thể lại không dễ dàng (điều này cũng tương tự như nguyên tắc
Dirichlet trong toán vậy) Khi giải bài toán bằng phương pháp này, chúng ta phải thực hiện hai yêu cầu quan trọng sau:
- Tìm công thức truy hồi xác định nghiệm bài toán qua nghiệm các bài toán con nhỏ hơn
- Với mỗi bài toán cụ thể, ta đề ra phương án lưu trữ nghiệm một cách hợp lý để từ đó có thể truy cập một cách thuận tiện nhất
Để minh hoạ thuật toán, ta xét một vài ví dụ
Ví dụ 1:Cho hai dãy số nguyên (a1,a2, ,am), (b1,b2, ,bn) Tìm dãy con chung có độ dài lớn nhất của hai dãy trên (coi dãy không có số nguyên nào là dãy con của mọi dãy và có
Trang 33Đây là trường hợp đặc biệt, có duy nhất một dãy con chung của hai dãy có độ dài? bằng
0 Vì vậy dãy con chung có độ dài lớn nhất của chúng có độ dài bằng 0
+Trường hợp 2: m 0 và n 0.
Trong trường hợp này, ta xét các bài toán nhỏ hơn là tìm dãy con chung có độ dài lớn nhất của hai dãy (a1,a2, ,ai), (b1,b2, ,bj) với 0 ≤ i ≤ m, 0 ≤ j ≤ n Go.i l[i,j] là độ dài của dãy con chung lớn nhất của hai dãy (a1, ,ai), (b1, ,bj) ; Như vậy ta phải tính tất cả các l[i,j] trong đó 0 <= i <= m, 0 <= j <= n
Chúng ta có thể thấy ngay rằng l[0,0]=0 Giả sử ta tính được l[s,t] với 1<S<t<j.<>
-Nếu ii bj thì l[i,j]=max{l[i-1,j], l[i,j-1]}
-Nếu ii</SUB>=Bj thì l[i,j]= 1+l[i-1,j-1].
Với những nhận xét trên, ta hoàn toàn tính được l[m,n] chính là độ dài dãy con chung dài nhất của (a1, am), (b1, bn)
Để tìm phần tử của dãy con, ta xuất phát từ ô l[m,n] tới ô l[0,0] Giả sử ta đang ở ô l[i,j] Nếu ai</SUB>=Bj thì ta thêm ai vào dãy con rồi nhảy tới ô 1] Nếu aibj thì l[i,j]=l[i-1,j] hoặc l[i,j]=l[i,j-1] Nếu l[i,j]=l[i-1,j] thì nhảy tới ô l[i-1,j], ngược lại thì nhảy tới ô l[i,j-1].
l[i-1,j-Sau đây là lời giải của bài toán Chương trình được viết bằng ngôn ngữ Pascal:
Trang 34while not(eoln(f)) do begin inc(i);read(f,a[i]);end;maxa:=i;
for i:=1 to maxa do for j:=1 to maxb do
if a[i]<>b[j] then kq[i,j]:=max(kq[i-1,j],kq[i,j-1])
else kq[i,j]:=kq[i-1,j-1]+1;
writeln('Do dai day con chung lon nhat:',kq[maxa,maxb]);
i:=maxa;j:=maxb;
while (i>0)or(j>0) do
if a[i]=b[j] then begin write(a[i]);dec(i);dec(j);end
else if kq[i-1,j]=kq[i,j] then dec(i) else dec(j);
end.
Với nội dung file?b2.inp? chứa 2 dãy (a1,a2, am) ,(b1,b2, bn) sau:
1 2 3 2 3 4 6
Trang 356 9 8 7
Xét bài toán kinh điển về tối ưu tổ hợp:
Ví dụ 2:Cho cái túi chứa được trọng lượng tối đa là w Có n đồ vật, đồ vật thứ i có khối lượng a[i] và giá trị c[i], 1≤ i ≤n Tìm cách xếp đồ vật vào túi sao
cho đạt giá trị lớn nhất
Lời giải
Gọi f(k,v) là giá trị lớn nhất của túi đựng trọng lượng v và chỉ chứa các đồ vật từ 1 đến k.
Nếu k=1 thì f(k,v)=(v div a[1])*c[1] Giả sử tính được f(s,t) với 1
Đặt: tg=v div a[k], f(k,v)=max{f(k-1,u)+x*c[k]}? (*) ,với x=0,1,2, ,tg, u=v-x*a[k]
Giá trị lớn nhất là f(n,w) Ta dùng mảng bản ghi a[1 n,1 w] chứa kết quả trung gian Mỗi bản ghi a[k,v] chứa giá trị f(k,v) và giá trị x thoả mãn công thức (*).
Để xác định số lượng x[i] đồ vật i thoả mãn điều kiện tối ưu, ta xuất phát từ a[n,w] xác định được x[n] Nhảy tới a[n-1,w-x[n]*a[n]] xác định được x[n-1]
Cứ như vậy tới x[1].
Sau đây là lời giải, chương trình được viết bằng ngôn ngữ Pascal:
a:array[1 10] of integer;{khoi luong}
c:array[1 10] of integer;{Gia tri}
i,j,tg,k,max,save:integer;
f:text;
b:array[1 n,1 w] of kq;
Trang 37số phần tử là dãy con của dãy đã cho.
Input: Dữ liệu vào được cho bởi tệp văn bản với quy cách:
- Dòng đầu ghi số N là số phần tử
Trang 38- Dòng tiếp theo ghi N số là các số nguyên của dãy.
ý tưởng của thuật toán quy hoạch động ở đây là: Để xây dựng dãy con dài nhất của dãy
đã cho chúng ta sẽ xây dựng dãy con dài nhất của đoạn phần tử đầu a1, a2, ai
Để làm được điều đó: ta gọi S[i] là số lượng phần tử nhiều nhất của dãy con tăng dần, trong đó ai cũng thuộc dãy con trên (nó là phần tử cuối cùng)
Chúng ta sẽ tính S[i] ở từng bước dựa vào các S[i-1], S[1] như sau:
Ban đầu S[i] với i = 1, 2, N được gán bằng 1 vì trường hợp xấu nhất thì dãy con chỉ là một phần tử
Với mỗi i >= 2 thì S[i] được tính bằng công thức truy hồi sau:
S[i]:=Max(S[j]+1) với j=i-1, 1 mà aj < ai
Để lấy lại dãy con cực đại ta dùng một mảng Truoc với ý nghĩa: Truoc[i] là chỉ số của phần tử trước phần tử i trong dãy con cực đại lấy trong dãy a1,a2, ai
Bây giờ chúng ta phải tìm vị trí i sao cho S[i] đạt max Ta lưu vị trí đó vào biến Luu
Như vậy: S[Luu] chính là số lượng phần tử của dãy con cực đại của dãy đã cho Và bằng mảng Truoc ta có thể lấy lại chỉ số các phần tử thuộc dãy con đó
Đến đây ta gặp một vấn đề: Mảng Truoc chỉ cho phép ta lần ngược từ cuối về đầu dó đó
để in ra các chỉ số theo thứ tự tăng dần ta phải dùng thêm một mảng phụ P và in ngược lại của mảng P:
Trang 39Chỉ số theo thứ tự tăng dần của dãy con cực đại được in ra bằng dòng lệnh:
For i:=dem downto 1 do Write(P[i],' ');
Tuy nhiên làm như trên có vẻ dài dòng trong khi chúng ta đã nhận ra tính đệ quy trong việc lấy ngược lại Và thủ tục in ra dãy con đã rất ngắn gọn và sáng sủa:
Công việc in ra chỉ cần một lời gọi: Print(Luu);
Ta có toàn văn chương trình:
Trang 40Var A : Array[1 MaxN] of Integer;
S : Array[1 MaxN] of Integer;Truoc : Array[1 MaxN] of Integer;i,j,Luu : Word;