Ta nói m t i t ng là quy n u nó c nh ngh a qua chính nó ho c m t i ng khác cùng d ng v i chính nó b ng quy n p. Ví d : t hai chi c g ng c u i di n nhau. Trong chi c g ng th nh t ch a hình chi c g ng th hai. Chi c g ng th hai l i ch a hình chi c g ng th nh t nên t t nhiên nó ch a l i hình nh c a chính nó trong chi c g ng th nh t... m t góc nhìn h p lý, ta có th th y m t dãy nh vô h n c a c hai chi c g ng. M t ví d khác là n u ng i ta phát hình tr c ti p phát thanh viên ng i bên máy vô tuy n truy n hình, trên màn hình c a máy này l i có chính hình nh c a phát thanh viên ó ng i bên máy vô tuy n truy n hình và c nh th ... Trong toán h c, ta c ng hay g p các nh ngh a quy: Giai th a c a n (n!): N u n = 0 thì n! = 1; n u n > 0 thì n! = n.(n-1)! 3.2. Gi i thu t quy N u l i gi i c a m t bài toán P c th c hi n b ng l i gi i c a bài toán P' có d ng gi ng nh P thì ó là m t l i gi i quy. Gi i thu t t ng ng v i l i gi i nh v y g i là gi i thu t quy. M i nghe thì có v h i l nh ng i m m u ch t c n l u ý là: P' tuy có d ng gi ng nh P, nh ng theo m t ngh a nào ó, nó ph i "nh " h n P, d gi i h n P và vi c gi i nó không c n dùng n P. nh ngh a m t hàm quy hay th t c quy g m hai ph n: − Ph n neo (anchor): ph n này c th c hi n khi mà công vi c quá n gi n, có th gi i tr c ti p ch không c n ph i nh n m t bài toán con nào c . − Ph n quy: trong tr ng h p bài toán ch a th gi i c b ng ph n neo, ta xác nh nh ng bài toán con và g i quy gi i nh ng bài toán con ó. Khi ã có l i gi i ( áp s ) c a nh ng bài toán con r i thì ph i h p chúng l i gi i bài toán ang quan tâm. Ph n quy th hi n tính "quy n p" c a l i gi i. Ph n neo c ng r t quan tr ng b i nó quy t nh t i tính h u h n d ng c a l i gi i. 3.3. Thi t k gi i thu t quy 3.3.1. Hàm n! int Factorial (int n) { // Nh n vào s t nhiên n và tr v n! if (n==0) return 1; // Ph n neo return n* Factorial (n-1); // Ph n quy } ây, ph n neo nh ngh a k t qu hàm t i n = 0, còn ph n quy ( ng v i n > 0) s nh ngh a k t qu hàm qua giá tr c a n và giai th a c a n - 1. Ví d : Dùng hàm này tính 3!, tr c h t nó ph i i tính 2! b i 3! c tính b ng tích c a 3 * 2!. T ng t tính 2!, nó l i i tính 1! b i 2! c tính b ng 2 * 1!. Áp d ng b c quy n p này thêm m t l n n a, 1! = 1 * 0!, và ta t t i tr ng h p c a ph n Ch ng 3. quy và gi i thu t quy Trang 21 u trúc d li u và gi i thu t neo, n ây t giá tr 1 c a 0!, nó tính c 1! = 1*1 = 1; t giá tr c a 1! nó tính c 2!; t giá tr c a 2! nó tính c 3!; cu i cùng cho k t qu là 6. 3.3.2. Dãy Fibonacci Dãy s Fibonacci b t ngu n t bài toán c v vi c sinh s n c a các c p th . Bài toán t ra nh sau: 1) Các con th không bao gi ch t 2) Hai tháng sau khi ra i, m i c p th m i s sinh ra m t c p th con (m t c, m t cái) 3) Khi ã sinh con r i thì c m i tháng ti p theo chúng l i sinh c m t c p con m i Gi s t u tháng 1 có m t c p m i ra i thì n gi a tháng th n s có bao nhiêu c p. Ví d , n = 5, ta th y: Gi a tháng th 1: 1 c p (ab) (c p ban u) Gi a tháng th 2: 1 c p (ab) (c p ban u v n ch a ) Gi a tháng th 3: 2 c p (AB)(cd) (c p ban u ra thêm 1 c p con) Gi a tháng th 4: 3 c p (AB)(cd)(ef) (c p ban u ti p t c ) Gi a tháng th 5: 5 c p (AB)(CD)(ef)(gh)(ik) (c c p (AB) và (CD) cùng ) Bây gi , ta xét t i vi c tính s c p th tháng th n: F(n) N u m i c p th tháng th n - 1 u sinh ra m t c p th con thì s c p th tháng th n s là: F(n) = 2 * F(n - 1) Nh ng v n không ph i nh v y, trong các c p th tháng th n - 1, ch có nh ng c p th ã có tháng th n - 2 m i sinh con tháng th n c thôi. Do ó F(n) = F(n - 1) + F(n - 2) (= s c + s sinh ra). V y có th tính c F(n) theo công th c sau: − F(n) = 1 n u n 2 − F(n) = F(n - 1) + F(n - 2) n u n > 2 int F(int n) { // Tính s c p th tháng th n if (n 2) return 1; // Ph n neo return F(n - 1) + F(n - 2); // Ph n quy } 3.3.3. Bài toán Tháp Hà N i ây là m t bài toán mang tính ch t m t trò ch i, n i dung n sau: Có n a ng kính hoàn toàn phân bi t, t ch ng lên nhau, các a c x p theo th t gi m d n c a ng kính tính t d i lên, a to nh t c t sát t. Có ba v trí có th t các a ánh s 1, 2, 3. Ch ng a ban u c t v trí 1:
1 2 3 Ng i ta mu n chuy n c ch ng a t v trí 1 sang v trí 2, theo nh ng u ki n:
Ch ng 3. quy và gi i thu t quy Trang 22
u trúc d li u và gi i thu t − Khi di chuy n m t a, ph i t nó vào m t trong ba v trí ã cho − M i l n ch có th chuy n m t a và ph i là a trên cùng − T i m t v trí, a nào m i chuy n n s ph i t lên trên cùng − a l n h n không bao gi c phép t lên trên a nh h n (hay nói cách khác: m t a ch c t trên m t t ho c t trên m t a l n h n) Trong tr ng h p có 2 a, cách làm có th mô t nh sau: Chuy n a nh sang v trí 3, a l n sang v trí 2 r i chuy n a nh t v trí 3 sang v trí 2. Nh ng ng i m i b t u có th gi i quy t bài toán m t cách d dàng khi s a là ít, nh ng h s g p r t nhi u khó kh n khi s các a nhi u h n. Tuy nhiên, v i t duy quy n p toán h c và m t máy tính thì công vi c tr nên khá d dàng: Có n a. − N u n = 1 thì ta chuy n a duy nh t ó t v trí 1 sang v trí 2 là xong. − Gi s r ng ta có ph ng pháp chuy n c n - 1 a t v trí 1 sang v trí 2, thì cách chuy n n - 1 a t v trí x sang v trí y (1 x, y 3) c ng t ng t . − Gi s ràng ta có ph ng pháp chuy n c n - 1 a gi a hai v trí b t k . chuy n n a t v trí x sang v trí y, ta g i v trí còn l i là z (= 6 - x - y). Coi a to nh t là ... m t t, chuy n n - 1 a còn l i t v trí x sang v trí z, sau ó chuy n a to nh t ó sang v trí y và cu i cùng l i coi a to nh t ó là m t t, chuy n n - 1 a còn l i ang v trí z sang v trí y ch ng lên a to nh t ó. Cách làm ó c th hi n trong th t c quy d i ây: void Move(int n, int x, int y) { // Th t c chuy n n a t v trí x sang v trí y if (n == 1) printf("\nChuyen 1 dia: %d --> %d", x, y); else { Move(n - 1, x, 6 - x - y); // Chuy n n - 1 a t x sang v trí còn l i Move(1, x, y); // Chuy n a to nh t t x sang y Move(n - 1, 6 - x - y, y); // Chuy n n - 1 a t v trí còn l i sang v trí y } } Ch ng trình chính r t n gi n, ch g m có 2 vi c: Nh p vào s n và g i Move(n, 1, 2). 3.4. Hi u l c c a quy Qua các ví d trên, ta có th th y quy là m t công c m nh gi i các bài toán. Có nh ng bài toán mà bên c nh gi i thu t quy v n có nh ng gi i thu t l p khá n gi n và h u hi u. Ch ng h n bài toán tính giai th a hay tính s Fibonacci. Tuy v y, quy v n có vai trò x ng áng c a nó, có nhi u bài toán mà vi c thi t k gi i thu t quy n gi n n nhi u so v i l i gi i l p và trong m t s t ng h p ch ng trình quy ho t ng nhanh h n ch ng trình vi t không có quy. Gi i thu t cho bài Tháp Hà N i và thu t toán s p x p ki u phân o n (Quick Sort) mà ta s nói t i trong các bài sau là nh ng ví d .
Ch ng 3. quy và gi i thu t quy Trang 23
u trúc d li u và gi i thu t Có m t m i quan h kh ng khít gi a quy và quy n p toán h c. Cách gi i quy cho m t bài toán d a trên vi c nh rõ l i gi i cho t ng h p suy bi n (neo) r i thi t k làm sao l i gi i c a bài toán c suy ra t l i gi i c a bài toán nh n cùng lo i nh th . T ng t nh v y, quy n p toán h c ch ng minh m t tính ch t nào ó ng v i s t nhiên c ng b ng cách ch ng minh tính ch t ó úng v i m t s t ng h p c s (th ng ng i ta ch ng minh nó úng v i 0 hay úng v i 1) và sau ó ch ng minh tính ch t ó s úng v i n b t k n u nó ã úng v i m i s t nhiên nh h n n. Do ó ta không l y làm ng c nhiên khi th y quy n p toán h c c dùng ch ng minh các tính ch t có liên quan t i gi i thu t quy. Ch ng h n: Ch ng minh s phép chuy n a gi i bài toán Tháp Hà N i v i n a là 2n-1:
− Rõ ràng là tính ch t này úng v i n = 1, b i ta c n 21 - 1 = 1 l n chuy n a
th c hi n yêu c u.
− V i n > 1; Gi s r ng chuy n n - 1 a gi a hai v trí ta c n 2n-1 - 1 phép
chuy n a, khi ó chuy n n a t v trí x sang v trí y, nhìn vào gi i thu t quy ta có th th y r ng trong t ng h p này nó c n (2n-1 - 1) + 1 + (2n-1 - 1) = 2 n - 1 phép chuy n a. Tính ch t c ch ng minh úng v i n. V y thì cô n g th c này s úng v i m i n. Th t áng ti c n u nh chúng ta ph i l p trình v i m t công c không cho phép quy, nh ng nh v y không có ngh a là ta bó tay tr c m t bài toán mang tính quy. M i gi i thu t quy u có cách thay th b ng m t gi i thu t không quy (kh quy), có th nói c n v y b i t t c các ch ng trình con quy s u c trình d ch chuy n thành nh ng mã l nh không quy t c khi giao cho máy tính th c hi n. Vi c tìm hi u cách kh quy m t cách "máy móc" nh các ch ng trình d ch thì ch c n hi u rõ c ch x p ch ng c a các th t c trong m t dây chuy n g i quy là có th làm c. Nh ng mu n kh quy m t cách tinh t thì ph i tùy thu c vào t ng bài toán mà kh quy cho khéo. Không ph i tìm âu xa, nh ng k thu t gi i công th c truy h i b ng quy ho ch ng là ví d cho th y tính ngh thu t trong nh ng cách ti p c n bài toán mang b n ch t quy tìm ra m t gi i thu t không quy y hi u qu .