SlideShare uma empresa Scribd logo
1 de 51
Baixar para ler offline
1
Bài 2: Đệ quy và GT đệ quy
2.1. Đệ quy và giải thuật đệ quy
2.2. Thiết kế giải thuật đệ quy
2.3. Một số dạng bài toán điển hình
2.4. Bài tập
2
2.1. Đệ quy và
giải thuật đệ quy
3
Đệ quy
Khái niệm: Một đối tượng là đệ quy nếu nó được định
nghĩa qua chính nó hoặc một đối tượng khác cùng dạng
với chính nó bằng quy nạp.
Phân loại: Có 2 loại đối tượng đệ quy.
Đệ quy trực tiếp: Đối tượng A được mô tả trực tiếp qua
chính đối tượng A.
Ví dụ: A mô tả qua A, B, C. Trong đó: B, C không chứa A.
Đệ quy gián tiếp: Đối tượng A được mô tả gián tiếp qua
đối tượng A.
Ví dụ: A mô tả qua B, C, D. Trong đó: B được mô tả qua A và E,
còn C và D không chứa A.
4
Minh hoạ đệ quy
1) Đệ quy trực tiếp 2) Đệ quy gián tiếp
A
B C
A
A A
C
E
B
D
5
Mô tả đệ quy
Điểm mạnh của đệ quy: Cho phép mô tả 1 tập lớn các
đối tượng bằng 1 số ít các mệnh đề hoặc mô tả 1 GT
phức tạp bằng 1 số ít các thao tác (1 chương trình con
đệ quy).
Mô tả đệ quy: gồm 2 phần
Phần neo: Mô tả các trường hợp suy biến của đối tượng
(giải thuật) qua 1 cấu trúc (thao tác) cụ thể xác định.
Phần đệ quy: Mô tả đối tượng (giải thuật) trong trường
hợp phổ biến thông qua chính đối tượng (giải thuật) đó 1
cách trực tiếp (đệ quy trực tiếp) hoặc gián tiếp (đệ quy
gián tiếp).
Chú ý: Nếu không có phần neo thì đối tượng được mô tả
có cấu trúc lớn vô hạn (giải thuật lặp không dừng)!
6
Một số mô tả đệ quy thường gặp
1. Tập số tự nhiên N:
0 là số tự nhiên. {phần neo}
X là số tự nhiên nếu X – 1 là số tự nhiên. {phần đệ quy}
2. Giai thừa của 1 số tự nhiên N:
0! = 1 {phần neo}
Nếu N > 0 thì N! = N * (N – 1)! {phần đệ quy}
3. Ước số chung lớn nhất (USCLN) của 2 số tự nhiên A
và B không đồng thời bằng 0 (A2 + B2 > 0)
USCLN(A, 0) = A {phần neo}
USCLN(A, B) = USCLN(B, A mod B) {phần đệ quy}
7
Câu hỏi kiểm tra nhận thức
Câu hỏi 1:
Giải thích mô tả đệ quy USCLN(A, B). Minh hoạ quá
trình thực hiện với:
1. A = 126 và B = 72.
2. A = 72 và B = 126.
Đáp án:
Giải thích:
Nếu B = 0 thì USCLN(A, B) = A.
Nếu B ≠ 0 thì thay A bằng B, thay B bằng A mod B
rồi lặp lại quá trình thực hiện.
USCLN(A, B) = USCLN(B, A mod B)
8
Câu hỏi kiểm tra nhận thức
Minh hoạ 1:
USCLN(126, 72) = USCLN(72, 54) //B = 72 ≠ 0
= USCLN(54, 18) //B = 54≠ 0
= USCLN(18, 0) //B = 18 ≠ 0
= 18 //B = 0
Minh hoạ 2:
USCLN(72, 126) = USCLN(126, 72) //B = 126 ≠ 0
= USCLN(72, 54) //B = 72 ≠ 0
= USCLN(54, 18) //B = 54 ≠ 0
= USCLN(18, 0) //B = 18 ≠ 0
= 18 //B = 0
9
Một số bài toán đệ quy điển hình
Bài toán tìm nghiệm gần đúng: của phương trình f(x)=0
trên đoạn [a, b] với sai số c, biết f(x) liên tục trên [a, b].
Bài toán “Tháp Hà Nội”: Chuyển một chồng đĩa N đĩa
với kích thước khác nhau từ cột A sang cột C theo cách:
Mỗi lần chỉ chuyển 1 đĩa .
Khi chuyển có thể dùng cột trung gian B.
Trong suốt quá trình chuyển, các chồng đĩa ở các cột luôn
được xếp đúng (đĩa có kích thước bé đặt trên đĩa có kích
thước lớn).
Bài toán “N quân Hậu”: Xếp N quân hậu trên bàn cờ
hình vuông kích thước N x N sao cho trên mỗi đường
chéo, đường ngang, đường dọc chỉ có đúng 1 quân Hậu.
10
Đặc điểm hàm đệ quy
Khái niệm: một chương trình con mô tả giải thuật đệ
quy gọi là chương trình con đệ quy, hay hàm đệ quy.
Pascal (hàm, thủ tục), C/C++ (hàm có kiểu, hàm void).
Đặc điểm: một hàm đệ quy có 3 đặc điểm sau
1. Có lời gọi đến chính nó: trong thân hàm đệ quy có chứa
lời gọi hàm tới chính hàm đệ quy đó.
2. Kích thước bài toán giảm dần: mỗi lần có lời gọi hàm đệ
quy thì kích thước của bài toán đã thu nhỏ hơn trước.
3. Có trường hợp suy biến: là trường hợp đặc biệt mà khi
xảy ra thì bài toán sẽ được giải quyết theo 1 cách khác
hẳn và quá trình gọi hàm đệ quy cũng kết thúc.
Kích thước bài toán giảm dần đảm bảo có trường hợp suy biến!
11
Đặc điểm hàm đệ quy
Phân loại: Có 2 loại hàm đệ quy, tương ứng với 2 loại
mô tả đệ quy.
Đệ quy trực tiếp: trong thân hàm A có chứa lời gọi hàm
đến chính A (thường gặp).
Bài toán giai thừa, USCLN, Fibonacci, Ackerman, tổ hợp,…
Đệ quy gián tiếp: trong thân hàm A chứa lời gọi hàm đến
hàm B, và trong thân hàm B lại chứa lời gọi hàm đến A
(ít gặp).
Giả thiết Collatz,...
12
Đệ quy gián tiếp: Giả thiết Collatz
Collatz đưa ra giả thuyết rằng:
“Với một số nguyên dương X bất kỳ, nếu X chẵn thì ta
gán X = X / 2; nếu X lẻ thì ta gán X = X * 3 + 1 thì sau
một số hữu hạn bước, ta sẽ có X = 1”.
Với X = 10, các bước tiến hành như sau:
1. X = 10 //X chẵn X = 10 / 2
2. X = 5 //X lẻ X = 5 * 3 + 1
3. X = 16 //X chẵn X = 16 / 2
4. X = 8 //X chẵn X = 8 / 2
5. X = 4 //X chẵn X = 4 / 2
6. X = 2 //X chẵn X = 2 / 2
7. X = 1 //Kết thúc
13
Đệ quy gián tiếp: Giả thiết Collatz
Bài toán (dựa trên khẳng định giả thuyết Collatz là
đúng):
“Cho trước số 1 cùng với hai phép toán * 2 và / 3, hãy sử
dụng một cách hợp lý hai phép toán đó để biến số 1
thành một số nguyên dương X cho trước.”
Ví dụ: X = 10 ta có biểu diễn 1 * 2 * 2 * 2 * 2 / 3 * 2 = 10.
Giải thuật:
Để biểu diễn X chia 2 trường hợp:
Nếu X chẵn, thì tìm cách biểu diễn số X / 2 và viết thêm
phép toán * 2 vào cuối.
Nếu X lẻ, thì tìm cách biểu diễn số X * 3 + 1 và viết thêm
phép toán / 3 vào cuối.
14
Đệ quy gián tiếp: Giả thiết Collatz
void XuLySoLe(int X) //khi X lẻ
{
XuLySo(X * 3 + 1);
printf(“ / 3”);
}
void XuLySoChan(int X) //khi X chẵn
{
XuLySo(X / 2);
printf(“ * 2”);
}
15
Đệ quy gián tiếp: Giả thiết Collatz
//In ra cách biểu diễn số X
void XuLySo(int X)
{
if (X == 1)
printf(“%d”, X);
else
if (X % 2 == 1) XuLySoLe(X);
else
XuLySoChan(X);
}
16
2.2. Thiết kế giải thuật đệ quy
2.2.1. Hàm N!
2.2.2. Dãy số Fibonacci
2.2.3. Chú ý
17
2.2.1. Hàm N!
Mô tả đệ quy:
1 nếu N = 0 (phần neo)
N! =
N * (N - 1)! nếu N > 0 (phần đệ quy)
Hàm đệ quy tính N! :
long GT(int N)
{
if (N == 0) return 1;
return N * GT(N – 1);
}
18
3 đặc điểm đệ quy của hàm N!
Đặc điểm:
Đối chiếu với đặc điểm hàm đệ quy:
Có lời gọi đến chính nó: hàm đệ quy GT(N) gọi đến hàm
GT(N – 1).
return N * GT(N – 1)
Kích thước bài toán giảm dần: sau mỗi lần gọi đệ quy,
giá trị của dữ liệu vào N giảm đi 1.
Có trường hợp suy biến: là trường hợp N = 0. Khi đó,
hàm GT(N) trả về giá trị 1 và đệ quy kết thúc.
if (N == 0) return 1;
19
GT lặp tính N!
Khái niệm:
Phương pháp sử dụng vòng lặp để giải bài toán đệ quy
gọi là khử đệ quy.
Giải thuật mô tả phương pháp khử đệ quy gọi là giải
thuật lặp.
Đặc điểm:
Ưu điểm:
Thường hiệu quả hơn đệ quy do không phải thực hiện nhiều lần
các thao tác: gọi hàm, cấp phát và giải phóng các biến cục bộ.
Không bị tràn bộ nhớ stack như đệ quy do không phải lưu trữ các
lời gọi trước.
Nhược điểm:
Việc tìm ra GT lặp thường khó khăn hơn nhiều GT đệ quy.
Việc lập trình thường phức tạp.
20
GT lặp tính N!
Mô tả không đệ quy: bài toán N! có thể mô tả theo
cách không đệ quy như sau:
N! = 1 * 2 * … * (N – 1) * N
N! là tích của N số tự nhiên liên tiếp từ 1 đến N!
Giải thuật lặp:
long GT(int N)
{
long p = 1;
for(int i = 2; i <= N; i++)
p = p * i;
return p;
}
Giải thuật lặp tính N! rất đơn giản!
21
Đánh giá độ phức tạp giải thuật
Phân tích đánh giá độ phức tạp của giải thuật lặp tính N!:
B1: Xác định phép toán tích cực:
p = p * i;
B2: Số lần thực hiện của phép toán tích cực là:
1 + 1 + … + 1 = N – 1 (lần)
B3: Kết luận độ phức tạp của giải thuật:
T(N) = O(N)
22
2.2.2. Dãy số Fibonacci
Khái niệm: 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ỏ.
Dãy số Fibonacci là mô hình của rất nhiều hiện tượng tự
nhiên và cũng được sử dụng nhiều trong tin học.
Bài toán:
1. Các con thỏ không bao giờ chết.
2. Hai tháng sau khi ra đời, 1 cặp thỏ mới sẽ sinh ra 1 cặp
thỏ con gồm (1 đực, 1 cái).
3. Khi đã sinh con rồi thì cứ mỗi tháng tiếp theo chúng lại
sinh ra được 1 cặp thỏ con mới.
Yêu cầu: Từ 1 cặp thỏ mới ra đời thì đến tháng thứ N sẽ
có bao nhiêu cặp thỏ?
23
Dãy số Fibonacci
Diễn giải quá trình sinh sản của thỏ:
Tháng thứ 1: 1 cặp (cặp ban đầu)
Tháng thứ 2: 1 cặp (cặp ban đầu vẫn chưa sinh)
Tháng thứ 3: 2 cặp (đã có thêm 1 cặp con)
Tháng thứ 4: 3 cặp (cặp đầu vẫn sinh thêm)
Tháng thứ 5: 5 cặp (cặp con bắt đầu sinh)
Tháng thứ 6: 8 cặp (cặp con vẫn sinh tiếp)
…
Tháng thứ N: ? cặp
Dãy số Fibonacci
1 1 2 3 5 8 … ?
24
Công thức tính số Fibonacci F(N)
Tìm công thứ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 con thì:
F(N) = 2 * F(N – 1)
Do 2 tháng sau khi được sinh ra, thỏ mới sinh con, nên
trong các cặp thỏ ở tháng thứ (N–1) chỉ có những cặp đã
có ở tháng thứ (N – 2) mới sinh con ở tháng thứ N.
Do đó số cặp thỏ ở tháng thứ N sẽ là:
F(N) = F(N – 2) + F(N – 1)
Mô tả đệ quy: tính F(N).
1 nếu N ≤ 2 //phần neo
F(N) =
F(N – 2) + F(N – 1) nếu N > 2 //phần đệ quy
25
GT đệ quy tính F(N)
Hàm đệ quy tính F(N):
long F(long N)
{
if (N <= 2) return 1;
return F(N – 2) + F(N – 1);
}
3 đặc điểm của hàm đệ quy:
1. Có lời gọi đến chính nó: return F(N – 2) + F(N – 1);
2. Kích thước bài toán giảm dần: N giảm thành N-1, N-2
3. Có trường hợp suy biến: F(1) = 1 và F(2) = 1
Chú ý: có 1 chi tiết hơi khác là trường hợp suy biến ứng
với 2 giá trị: F(1) = 1 và F(2) = 1
26
Giải thuật lặp tính F(N)
Giải thuật lặp:
long F(long N)
{
if (N <= 2) return 1;
Fib1 = 1;
Fib2 = 1;
for(long i = 3; i <= N; i++)
{
Fibn = Fib1 + Fib2;
Fib1 = Fib2;
Fib2 = Fibn;
}
return Fibn;
}
27
Đánh giá độ phức tạp giải thuật
Phân tích độ phức tạp của giải thuật lặp tính F(N):
B1: Xác định phép toán tích cực:
Fibn = Fib1 + Fib2;
Fib1 = Fib2;
Fib2 = Fibn;
B2: Xác định số lần thực hiện của phép toán tích cực:
1 + 1 + … + 1 = N – 2 (lần)
B3: Kết luận độ phức tạp của giải thuật lặp là:
T(N) = O(N)
28
2.3. Một số dạng bài điển hình
2.3.1. Bài toán đếm
2.3.2. Bài toán liệt kê
2.3.3. Bài toán tối ưu
29
Một số dạng bài điển hình
Bài toán đếm: trong tập các đối tượng cho trước, có bao
nhiêu đối tượng thỏa mãn những điều kiện nhất định.
Có bao nhiêu số nguyên tố không lớn hơn N?
Bài toán liệt kê: trong tập các đối tượng cho trước, liệt
kê cấu hình của tất cả những đối tượng thỏa mãn những
điều kiện nhất định.
Liệt kê các số nguyên tố không lớn hơn N?
Bài toán tối ưu: trong tập các đối tượng cho trước, tìm
cấu hình của đối tượng thỏa mãn những điều kiện nhất
định và là tốt nhất theo một tiêu chí cụ thể.
Tìm số nguyên tố lớn nhất trong các số nguyên tố không
lớn hơn N?
30
2.3.1. Bài toán đếm
Bài toán đếm: trong tập các đối tượng cho trước, có bao
nhiêu đối tượng thỏa mãn những điều kiện nhất định.
Ví dụ:
Có bao nhiêu số nguyên tố không lớn hơn N?
Có bao nhiêu xâu nhị phân độ dài N không chứa xâu ‘00’?
Phương pháp giải:
Công thức toán học + nguyên lý đếm cơ bản (cộng, nhân, bù trừ).
Công thức truy hồi (phương trình truy hồi tuyến tính thuần nhất,
đệ quy, quy hoạch động).
Bài toán liệt kê: sử dụng phương pháp liệt kê để giải bài toán
đếm, chỉ được sử dụng khi không tìm ra cách giải nào khác.
Nhận xét:
Bài toán đếm thường xuyên xuất hiện trong các bài thi OLP vì có
nhiều khả năng cải tiến thuật giải để giảm thời gian chạy!
31
2.3.1. Bài toán đếm
Bài toán: Xóa số (OLP Không chuyên 2012)
Cho dãy số nguyên không âm a1, a2, …, an. Người ta
tiến hành chọn ra 2 chỉ số i, j sao cho 1 ≤ i < j ≤ n và xóa
khỏi dãy 2 số ai, aj để tổng giá trị các số còn lại trong
dãy là số chẵn.
Yêu cầu: Cho dãy số a1, a2, …, an. Hãy đếm số lượng
cách chọn 2 chỉ số i, j thỏa mãn. Hai cách chọn khác
nhau nếu tồn tại một chỉ số khác nhau.
Dữ liệu: vào từ file văn bản DEL.INP:
Dòng 1: chứa số nguyên n (n ≤ 106).
Dòng 2: chứa n số nguyên không âm a1, a2, …, an (ai ≤ 109).
Kết quả: đưa ra file văn bản DEL.OUT một số nguyên là
số cách chọn 2 chỉ số thỏa mãn.
32
2.3.1. Bài toán đếm
Ví dụ:
Giải thích:
Có 6 cách chọn 2 số (i, j) để xóa khỏi dãy để tổng còn lại là số
chẵn.
(1, 2) (1, 4)
(2, 3) (2, 5)
(3, 4)
(4, 5)
65
1 2 3 4 5
DEL.OUTDEL.INP
33
2.3.1. Bài toán đếm
B1: Xác định bài toán
Vấn đề cần giải quyết: đếm số cách xóa các cặp (ai, aj)
để tổng còn lại là số chẵn.
Giả thiết: có n số nguyên a1, a2, …, an.
Yêu cầu: số nguyên là số cách xóa.
B2: Tìm cấu trúc dữ liệu
n: kiểu số nguyên 4 byte.
a: kiểu mảng 1 chiều của kiểu số nguyên 4 byte.
Biến kết quả kq: kiểu số nguyên 8 byte.
Chú ý: nếu mọi cách xóa 1 cặp (ai, aj) khỏi dãy số đều thỏa mãn
điều kiện tổng còn lại là số chẵn thì số cách xóa tối đa (n = 106)
là: n(n-1) / 2 = 5 * 1011 cách
34
2.3.1. Bài toán đếm
B3: Tìm giải thuật
GT 1:
Ý tưởng: “vét cạn”, duyệt tất cả các phương án xóa số để tìm ra
số cách kq. Đây chính là ý tưởng của bài toán liệt kê.
Mô tả:
kq = 0; sum = 0; //Tính tổng dãy số a
for(i = 0; i < n; i++) sum = sum + a[i];
for(i = 0; i < n – 1; i++)
for(j = i + 1; j < n; j++)
{
tong = sum – a[i] – a[j]; //Tổng còn lại
if (tong % 2 == 0) kq = kq + 1; //Đếm
}
Đánh giá: Độ phức tạp GT 1 thuộc phân lớp N2.
35
2.3.1. Bài toán đếm
GT 2:
Ý tưởng: sử dụng “nguyên lý đếm”.
Gọi sum là tổng các phần tử của dãy a[], x là số phần tử lẻ
y = n – x là số phần tử chẵn.
- Nếu sum chẵn thì phải xóa 2 số lẻ hoặc 2 số chẵn. Kết quả:
kq = x(x-1)/2 + y(y-1)/2
- Nếu sum lẻ thì phải xóa 1 số lẻ và 1 số chẵn. Kết quả:
kq = xy
36
2.3.1. Bài toán đếm
Mô tả:
//B1: Tính tổng dãy số a và số phần tử lẻ x
sum = 0;
x = 0;
for(i = 0; i < n; i++)
{
sum = sum + a[i];
if (a[i] % 2 == 1) x = x + 1;
}
y = n – x; //Số phần tử chẵn
//B2: Áp dụng nguyên lý đếm
if(sum % 2 == 0) kq = x * (x – 1) / 2 + y * (y – 1) / 2;
else kq = x * y;
Đánh giá: Độ phức tạp GT 2 thuộc phân lớp N.
37
2.3.2. Bài toán liệt kê
Bài toán liệt kê: trong tập các đối tượng cho trước, liệt
kê cấu hình của tất cả những đối tượng thỏa mãn những
điều kiện nhất định.
Bài toán liệt kê cũng thuộc lớp bài toán đếm!
Ví dụ:
Liệt kê các số nguyên tố không lớn hơn N?
Liệt kê các xâu nhị phân độ dài N không chứa xâu ‘00’?
Phương pháp giải:
Phương pháp sinh (generation): “hợp lý”, khó áp dụng.
Thuật toán quay lui (backtracking algorithms): phổ biến.
Nhận xét:
Bài toán liệt kê hiếm khi xuất hiện trong các bài thi OLP vì có thời
gian chạy lớn, khó có khả năng cải tiến thuật giải!
38
Phương pháp sinh
Điều kiện áp dụng:
Có thể xác định được 1 thứ tự trên tập các cấu hình cần
liệt kê, cấu hình đầu tiên, cấu hình cuối cùng.
Xây dựng được thuật toán từ 1 cấu hình chưa phải cấu
hình cuối cùng, sinh ra cấu hình kế tiếp.
Mô tả:
<Xây dựng cấu hình đầu tiên>;
do {
<Liệt kê cấu hình hiện tại>;
<Sinh cấu hình kế tiếp từ cấu hình hiện tại>;
}
while (<Chưa phải cấu hình cuối cùng>)
39
Phương pháp sinh
Bài toán: Liệt kê các xâu nhị phân độ dài N
Thứ tự: thứ tự từ điển (0, 1) tính từ phải sang trái.
Cấu hình đầu tiên: 0 0 … 0
Cấu hình cuối cùng: 1 1 … 1
Phương pháp sinh:
Xét xâu nhị phân từ phải sang trái, tìm số 0 đầu tiên.
Tìm thấy: thay 0 bằng 1, cho các phần tử phía sau vị trí đó bằng 0
Không tìm thấy: là cấu hình cuối cùng. Kết thúc.
Ví dụ: N = 5
Cấu hình hiện tại: 1 0 0 1 1
Tìm số 0 đầu tiên: 1 0 0 1 1
Thay 0 bằng 1: 1 0 1 1 1
Cấu hình kế tiếp: 1 0 1 0 0
40
Phương pháp sinh
Bài toán: Liệt kê các tập con K phần tử
Thứ tự: thứ tự từ điển (1, 2, …, N) tính từ phải sang trái.
Cấu hình đầu tiên: 1 2 … K
Cấu hình cuối cùng: N-K+1 N-K+2 … N
Phương pháp sinh:
Xét tập con từ phải sang trái, tìm phần tử đầu tiên (x[i]) chưa đạt
giới hạn trên (N-K+i).
Tăng x[i] lên 1, các pt sau (x[j]) bằng giới hạn dưới (x[j-1]+1).
Không tìm thấy: là cấu hình cuối cùng. Kết thúc.
Ví dụ: N = 9, K = 5
Cấu hình hiện tại: 1 3 7 8 9
Tìm phần tử đầu tiên chưa đạt giới hạn trên: 1 3 7 8 9
Tăng phần tử tìm được x[i] lên 1: 1 4 7 8 9
Cấu hình kế tiếp: 1 4 5 6 7
41
Phương pháp sinh
Bài toán: Dãy số (OLP Không chuyên 2008)
Một sinh viên Trường ĐH Kỹ thuật Công nghệ đang
nghiên cứu về bài toán dãy số: tìm số An của dãy A0,
A1, A2,…, trong đó
A0 = 0,
Ai là số nguyên dương nhỏ nhất lớn hơn Ai-1 và trong biểu diễn
thập phân của Ai không chứa các chữ số trong biểu diễn thập
phân của Ai với i ≥ 1.
Như vậy các phần tử đầu tiên của dãy A là:
50
14
41
13
…3022109876543210A[i]
…1211109876543210i
42
Phương pháp sinh
Yêu cầu: Cho số tự nhiên n. Hãy tìm An.
Dữ liệu: vào từ file văn bản NUMSEG.INP trong đó
chứa duy nhất số n (0 ≤ n ≤ 500).
Kết quả: ghi ra file văn bản NUMSEG.OUT giá trị An.
Ví dụ:
00
3012
91127
NUMSEG.OUTNUMSEG.INP
43
Thuật toán quay lui
Ý tưởng: Xây dựng cấu hình liệt kê x[1..n] bằng cách
thử tất cả các khả năng của từng phần tử x[i].
Cho x[1] nhận lần lượt các giá trị có thể. Với mỗi x[1]:
Cho x[2] nhận lần lượt các giá trị có thể. Với mỗi x[2]:
• …
Cho x[n] nhận lần lượt các giá trị có thể. Với mỗi
x[n], ta có 1 cấu hình x[1..n]
Nhận xét:
Ý tưởng của thuật toán quay lui là “duyệt toàn bộ”.
Có thể giải được hầu hết các bài toán tổ hợp.
Chỉ sử dụng thuật toán quay lui để giải các bài toán đếm,
tối ưu khi không còn lựa chọn nào khác.
44
Thuật toán quay lui
Mô tả:
void try(i) //Cho x[i] nhận lần lượt các giá trị có thể
{
for (<Mọi giá trị V có thể gán cho x[i]>)
{
x[i] = V;
if (i == n)
<Thông báo cấu hình tìm được>;
else
try(i+1); //Gọi đệ quy để chọn x[i+1]
}
}
45
Thuật toán quay lui
Điều kiện áp dụng:
Tìm được tập giá trị có thể của 1 phần tử x[i] bất kỳ trong
cấu hình x[1..n].
Đối với các bài toán tổ hợp, điều kiện này thường dễ
dàng tìm được!
Bài toán:
Liệt kê xâu nhị phân độ dài N: tập giá trị của 1 phần tử
x[i] trong xâu là (0, 1).
46
2.3.3. Bài toán tối ưu
Bài toán tối ưu: trong tập các đối tượng cho trước, tìm
cấu hình của đối tượng thỏa mãn những điều kiện nhất
định và là tốt nhất theo một tiêu chí cụ thể.
Ví dụ:
Tìm số nguyên tố lớn nhất trong các số nguyên tố ≤ N?
Bài toán Mật độ giao thông – OLP 2012: tìm độ lệch của hai
đoạn đường có tình trạng giao thông giống nhau nhất?
Phương pháp giải: rất đa dạng
Phương pháp quy hoạch động (dynamic programming).
Thuật toán tham lam (greedy algorithms).
Thuật toán quay lui: kỹ thuật nhánh cận
Nhận xét:
Bài toán tối ưu thường xuyên xuất hiện trong các bài thi OLP,
cũng như trong các bài toán thực tế
47
2.4. Câu hỏi ôn tập
1. Hàm Ackermann:
Cho mô tả đệ quy:
N + 1 nếu M = 0
Acker(M, N) = Acker(M – 1, 1) nếu N = 0
Acker(M – 1, Acker(M, N – 1)) còn lại
(Hàm Ackermann có đặc điểm là giá trị tăng rất nhanh khi
đối số M, N tăng, M và N là các giá trị nguyên)
a) Chỉ rõ phần neo và phần đệ quy trong mô tả.
b) Minh họa quá trình tìm Acker(1, 2).
c) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3
đặc điểm của hàm đệ quy.
48
2.4. Câu hỏi ôn tập
2. Bài toán Fibonacci:
Tìm phần tử thứ N trong dãy số Fibonacci.
a) Nêu mô tả đệ quy và chỉ rõ phần neo và phần đệ quy.
b) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3
đặc điểm của hàm đệ quy.
c) Minh họa quá trình tìm F(5).
d) Viết hàm tính giá trị của hàm bằng giải thuật lặp. Phân
tích đánh giá giải thuật trong trường hợp trung bình.
49
2.4. Câu hỏi ôn tập
3. Bài toán Ước số chung lớn nhất bằng phép chia:
Tìm USCLN(A, B) với A và B là các số tự nhiên không
đồng thời bằng 0.
a) Nêu mô tả đệ quy và chỉ rõ phần neo và phần đệ quy.
b) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3
đặc điểm của hàm đệ quy.
c) Minh họa quá trình tìm USCLN(234, 198).
d) Viết hàm tính giá trị của hàm bằng giải thuật lặp. Phân
tích đánh giá giải thuật trong trường hợp tốt nhất.
50
2.4. Câu hỏi ôn tập
4. Bài toán Ước số chung lớn nhất bằng phép trừ:
Tìm USCLN(A, B) với A và B là các số tự nhiên không
đồng thời bằng 0.
a) Nêu mô tả đệ quy và chỉ rõ phần neo và phần đệ quy.
b) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3
đặc điểm của hàm đệ quy.
c) Minh họa quá trình tìm USCLN(126, 72).
51
2.4. Câu hỏi ôn tập
5. Hàm tổ hợp: Cho mô tả đệ quy:
1 nếu K = 0 hoặc K = N
C(N, K) =
C(N – 1, K) + C(N – 1, K – 1) nếu 0 < K < N
a) Chỉ rõ phần neo và phần đệ quy trong mô tả.
b) Minh họa quá trình tìm C(5, 2).
c) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3
đặc điểm của hàm đệ quy.
d) Viết hàm tính giá trị của hàm bằng giải thuật lặp theo
công thức sau:
K!K)!(N
N!
K)C(N,
−
=

Mais conteúdo relacionado

Mais procurados

KTMT Số Nguyên - Số Chấm Động
KTMT Số Nguyên - Số Chấm ĐộngKTMT Số Nguyên - Số Chấm Động
KTMT Số Nguyên - Số Chấm Động
David Nguyen
 
[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...
[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...
[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...
Nguyen Vietnam
 
đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )
Bui Loi
 
Phần 10: Dữ liệu kiểu cấu trúc
Phần 10: Dữ liệu kiểu cấu trúcPhần 10: Dữ liệu kiểu cấu trúc
Phần 10: Dữ liệu kiểu cấu trúc
Huy Rùa
 
Bộ đề toán rời rạc thi cao học
Bộ đề toán rời rạc thi cao họcBộ đề toán rời rạc thi cao học
Bộ đề toán rời rạc thi cao học
Nấm Lùn
 

Mais procurados (20)

Quy hoach tuyen tinh C1
Quy hoach tuyen tinh C1Quy hoach tuyen tinh C1
Quy hoach tuyen tinh C1
 
Chuong04
Chuong04Chuong04
Chuong04
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
Giáo trình Phân tích và thiết kế giải thuật - CHAP 5
 
KTMT Số Nguyên - Số Chấm Động
KTMT Số Nguyên - Số Chấm ĐộngKTMT Số Nguyên - Số Chấm Động
KTMT Số Nguyên - Số Chấm Động
 
Giải bài tập Phương pháp tính
Giải bài tập Phương pháp tínhGiải bài tập Phương pháp tính
Giải bài tập Phương pháp tính
 
Gt khong gian_metric Nguyen Hoang
Gt khong gian_metric Nguyen HoangGt khong gian_metric Nguyen Hoang
Gt khong gian_metric Nguyen Hoang
 
Giáo trình Phân tích và thiết kế giải thuật - CHAP 2
Giáo trình Phân tích và thiết kế giải thuật - CHAP 2Giáo trình Phân tích và thiết kế giải thuật - CHAP 2
Giáo trình Phân tích và thiết kế giải thuật - CHAP 2
 
[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...
[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...
[Math educare.com] giai tich ham nhieu bien-phep tinh vi tich phan ham nhieu ...
 
Hoán vị lặp tổ hợp
Hoán vị lặp tổ hợpHoán vị lặp tổ hợp
Hoán vị lặp tổ hợp
 
30 bài toán phương pháp tính
30 bài toán phương pháp tính30 bài toán phương pháp tính
30 bài toán phương pháp tính
 
04 mat102-bai 1-v1.0
04 mat102-bai 1-v1.004 mat102-bai 1-v1.0
04 mat102-bai 1-v1.0
 
đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )
 
Bài 5: Các thuật toán sắp xếp và tìm kiếm cơ bản - Giáo trình FPT
Bài 5: Các thuật toán sắp xếp và tìm kiếm cơ bản - Giáo trình FPTBài 5: Các thuật toán sắp xếp và tìm kiếm cơ bản - Giáo trình FPT
Bài 5: Các thuật toán sắp xếp và tìm kiếm cơ bản - Giáo trình FPT
 
Chuong02
Chuong02Chuong02
Chuong02
 
Phần 10: Dữ liệu kiểu cấu trúc
Phần 10: Dữ liệu kiểu cấu trúcPhần 10: Dữ liệu kiểu cấu trúc
Phần 10: Dữ liệu kiểu cấu trúc
 
Bộ đề toán rời rạc thi cao học
Bộ đề toán rời rạc thi cao họcBộ đề toán rời rạc thi cao học
Bộ đề toán rời rạc thi cao học
 
Lập trình hướng đối tượng - p3
Lập trình hướng đối tượng - p3Lập trình hướng đối tượng - p3
Lập trình hướng đối tượng - p3
 
Toán rời rạc-Dành cho sinh viên,người thi cao học
Toán rời rạc-Dành cho sinh viên,người thi cao họcToán rời rạc-Dành cho sinh viên,người thi cao học
Toán rời rạc-Dành cho sinh viên,người thi cao học
 
Tom tat cong thuc XSTK
Tom tat cong thuc XSTKTom tat cong thuc XSTK
Tom tat cong thuc XSTK
 
Chuong 3
Chuong 3Chuong 3
Chuong 3
 

Semelhante a Chuong 2. de quy dai hoc

Chuong+1 ______
Chuong+1  ______Chuong+1  ______
Chuong+1 ______
Phi Phi
 
Bdhsg toan 9 cuc ha ydoc
Bdhsg toan 9  cuc ha ydocBdhsg toan 9  cuc ha ydoc
Bdhsg toan 9 cuc ha ydoc
Tam Vu Minh
 
Bài Tập Xử Lí Tín Hiệu Số
Bài Tập Xử Lí Tín Hiệu SốBài Tập Xử Lí Tín Hiệu Số
Bài Tập Xử Lí Tín Hiệu Số
viethung094
 

Semelhante a Chuong 2. de quy dai hoc (20)

304686218-Chia-đoi-tập-vdgdhợp-2.docx
304686218-Chia-đoi-tập-vdgdhợp-2.docx304686218-Chia-đoi-tập-vdgdhợp-2.docx
304686218-Chia-đoi-tập-vdgdhợp-2.docx
 
Gt de quy_2
Gt de quy_2Gt de quy_2
Gt de quy_2
 
Gt de quy
Gt de quyGt de quy
Gt de quy
 
chuyen de dai so
 chuyen de dai so  chuyen de dai so
chuyen de dai so
 
Thuật toán berlekamp và đa thức chia đường tròn modulo p
Thuật toán berlekamp và đa thức chia đường tròn modulo pThuật toán berlekamp và đa thức chia đường tròn modulo p
Thuật toán berlekamp và đa thức chia đường tròn modulo p
 
Diophantine equations Phương trình diophant
Diophantine equations Phương trình diophantDiophantine equations Phương trình diophant
Diophantine equations Phương trình diophant
 
CHUYÊN ĐỀ SỐ HỌC ÔN THI VÀO LỚP 10 CÁC TRƯỜNG CHUYÊN
CHUYÊN ĐỀ SỐ HỌC ÔN THI VÀO LỚP 10 CÁC TRƯỜNG CHUYÊNCHUYÊN ĐỀ SỐ HỌC ÔN THI VÀO LỚP 10 CÁC TRƯỜNG CHUYÊN
CHUYÊN ĐỀ SỐ HỌC ÔN THI VÀO LỚP 10 CÁC TRƯỜNG CHUYÊN
 
10 mat102-bai 7-v1.0
10 mat102-bai 7-v1.010 mat102-bai 7-v1.0
10 mat102-bai 7-v1.0
 
Chuong+1 ______
Chuong+1  ______Chuong+1  ______
Chuong+1 ______
 
Chuong+1 ______
Chuong+1  ______Chuong+1  ______
Chuong+1 ______
 
De cuong lop 10 (17 18) ham so bac hai va pt
De cuong lop 10 (17 18) ham so bac hai va ptDe cuong lop 10 (17 18) ham so bac hai va pt
De cuong lop 10 (17 18) ham so bac hai va pt
 
Nhị thức newton và Phương pháp giải các bài tập về Nhị thức newton
Nhị thức newton và Phương pháp giải các bài tập về Nhị thức newtonNhị thức newton và Phương pháp giải các bài tập về Nhị thức newton
Nhị thức newton và Phương pháp giải các bài tập về Nhị thức newton
 
07 mat101 bai3_v2.3013101225
07 mat101 bai3_v2.301310122507 mat101 bai3_v2.3013101225
07 mat101 bai3_v2.3013101225
 
Cau truc du_lieu_dac_biet
Cau truc du_lieu_dac_bietCau truc du_lieu_dac_biet
Cau truc du_lieu_dac_biet
 
Sophuc
SophucSophuc
Sophuc
 
BỘ ĐỀ THI QUỐC GIA DANAMATH
BỘ ĐỀ THI QUỐC GIA DANAMATHBỘ ĐỀ THI QUỐC GIA DANAMATH
BỘ ĐỀ THI QUỐC GIA DANAMATH
 
chuyen de so hoc vao 10
 chuyen de so hoc vao 10  chuyen de so hoc vao 10
chuyen de so hoc vao 10
 
Dãy số vmo2009
Dãy số vmo2009Dãy số vmo2009
Dãy số vmo2009
 
Bdhsg toan 9 cuc ha ydoc
Bdhsg toan 9  cuc ha ydocBdhsg toan 9  cuc ha ydoc
Bdhsg toan 9 cuc ha ydoc
 
Bài Tập Xử Lí Tín Hiệu Số
Bài Tập Xử Lí Tín Hiệu SốBài Tập Xử Lí Tín Hiệu Số
Bài Tập Xử Lí Tín Hiệu Số
 

Chuong 2. de quy dai hoc

  • 1. 1 Bài 2: Đệ quy và GT đệ quy 2.1. Đệ quy và giải thuật đệ quy 2.2. Thiết kế giải thuật đệ quy 2.3. Một số dạng bài toán điển hình 2.4. Bài tập
  • 2. 2 2.1. Đệ quy và giải thuật đệ quy
  • 3. 3 Đệ quy Khái niệm: Một đối tượng là đệ quy nếu nó được định nghĩa qua chính nó hoặc một đối tượng khác cùng dạng với chính nó bằng quy nạp. Phân loại: Có 2 loại đối tượng đệ quy. Đệ quy trực tiếp: Đối tượng A được mô tả trực tiếp qua chính đối tượng A. Ví dụ: A mô tả qua A, B, C. Trong đó: B, C không chứa A. Đệ quy gián tiếp: Đối tượng A được mô tả gián tiếp qua đối tượng A. Ví dụ: A mô tả qua B, C, D. Trong đó: B được mô tả qua A và E, còn C và D không chứa A.
  • 4. 4 Minh hoạ đệ quy 1) Đệ quy trực tiếp 2) Đệ quy gián tiếp A B C A A A C E B D
  • 5. 5 Mô tả đệ quy Điểm mạnh của đệ quy: Cho phép mô tả 1 tập lớn các đối tượng bằng 1 số ít các mệnh đề hoặc mô tả 1 GT phức tạp bằng 1 số ít các thao tác (1 chương trình con đệ quy). Mô tả đệ quy: gồm 2 phần Phần neo: Mô tả các trường hợp suy biến của đối tượng (giải thuật) qua 1 cấu trúc (thao tác) cụ thể xác định. Phần đệ quy: Mô tả đối tượng (giải thuật) trong trường hợp phổ biến thông qua chính đối tượng (giải thuật) đó 1 cách trực tiếp (đệ quy trực tiếp) hoặc gián tiếp (đệ quy gián tiếp). Chú ý: Nếu không có phần neo thì đối tượng được mô tả có cấu trúc lớn vô hạn (giải thuật lặp không dừng)!
  • 6. 6 Một số mô tả đệ quy thường gặp 1. Tập số tự nhiên N: 0 là số tự nhiên. {phần neo} X là số tự nhiên nếu X – 1 là số tự nhiên. {phần đệ quy} 2. Giai thừa của 1 số tự nhiên N: 0! = 1 {phần neo} Nếu N > 0 thì N! = N * (N – 1)! {phần đệ quy} 3. Ước số chung lớn nhất (USCLN) của 2 số tự nhiên A và B không đồng thời bằng 0 (A2 + B2 > 0) USCLN(A, 0) = A {phần neo} USCLN(A, B) = USCLN(B, A mod B) {phần đệ quy}
  • 7. 7 Câu hỏi kiểm tra nhận thức Câu hỏi 1: Giải thích mô tả đệ quy USCLN(A, B). Minh hoạ quá trình thực hiện với: 1. A = 126 và B = 72. 2. A = 72 và B = 126. Đáp án: Giải thích: Nếu B = 0 thì USCLN(A, B) = A. Nếu B ≠ 0 thì thay A bằng B, thay B bằng A mod B rồi lặp lại quá trình thực hiện. USCLN(A, B) = USCLN(B, A mod B)
  • 8. 8 Câu hỏi kiểm tra nhận thức Minh hoạ 1: USCLN(126, 72) = USCLN(72, 54) //B = 72 ≠ 0 = USCLN(54, 18) //B = 54≠ 0 = USCLN(18, 0) //B = 18 ≠ 0 = 18 //B = 0 Minh hoạ 2: USCLN(72, 126) = USCLN(126, 72) //B = 126 ≠ 0 = USCLN(72, 54) //B = 72 ≠ 0 = USCLN(54, 18) //B = 54 ≠ 0 = USCLN(18, 0) //B = 18 ≠ 0 = 18 //B = 0
  • 9. 9 Một số bài toán đệ quy điển hình Bài toán tìm nghiệm gần đúng: của phương trình f(x)=0 trên đoạn [a, b] với sai số c, biết f(x) liên tục trên [a, b]. Bài toán “Tháp Hà Nội”: Chuyển một chồng đĩa N đĩa với kích thước khác nhau từ cột A sang cột C theo cách: Mỗi lần chỉ chuyển 1 đĩa . Khi chuyển có thể dùng cột trung gian B. Trong suốt quá trình chuyển, các chồng đĩa ở các cột luôn được xếp đúng (đĩa có kích thước bé đặt trên đĩa có kích thước lớn). Bài toán “N quân Hậu”: Xếp N quân hậu trên bàn cờ hình vuông kích thước N x N sao cho trên mỗi đường chéo, đường ngang, đường dọc chỉ có đúng 1 quân Hậu.
  • 10. 10 Đặc điểm hàm đệ quy Khái niệm: một chương trình con mô tả giải thuật đệ quy gọi là chương trình con đệ quy, hay hàm đệ quy. Pascal (hàm, thủ tục), C/C++ (hàm có kiểu, hàm void). Đặc điểm: một hàm đệ quy có 3 đặc điểm sau 1. Có lời gọi đến chính nó: trong thân hàm đệ quy có chứa lời gọi hàm tới chính hàm đệ quy đó. 2. Kích thước bài toán giảm dần: mỗi lần có lời gọi hàm đệ quy thì kích thước của bài toán đã thu nhỏ hơn trước. 3. Có trường hợp suy biến: là trường hợp đặc biệt mà khi xảy ra thì bài toán sẽ được giải quyết theo 1 cách khác hẳn và quá trình gọi hàm đệ quy cũng kết thúc. Kích thước bài toán giảm dần đảm bảo có trường hợp suy biến!
  • 11. 11 Đặc điểm hàm đệ quy Phân loại: Có 2 loại hàm đệ quy, tương ứng với 2 loại mô tả đệ quy. Đệ quy trực tiếp: trong thân hàm A có chứa lời gọi hàm đến chính A (thường gặp). Bài toán giai thừa, USCLN, Fibonacci, Ackerman, tổ hợp,… Đệ quy gián tiếp: trong thân hàm A chứa lời gọi hàm đến hàm B, và trong thân hàm B lại chứa lời gọi hàm đến A (ít gặp). Giả thiết Collatz,...
  • 12. 12 Đệ quy gián tiếp: Giả thiết Collatz Collatz đưa ra giả thuyết rằng: “Với một số nguyên dương X bất kỳ, nếu X chẵn thì ta gán X = X / 2; nếu X lẻ thì ta gán X = X * 3 + 1 thì sau một số hữu hạn bước, ta sẽ có X = 1”. Với X = 10, các bước tiến hành như sau: 1. X = 10 //X chẵn X = 10 / 2 2. X = 5 //X lẻ X = 5 * 3 + 1 3. X = 16 //X chẵn X = 16 / 2 4. X = 8 //X chẵn X = 8 / 2 5. X = 4 //X chẵn X = 4 / 2 6. X = 2 //X chẵn X = 2 / 2 7. X = 1 //Kết thúc
  • 13. 13 Đệ quy gián tiếp: Giả thiết Collatz Bài toán (dựa trên khẳng định giả thuyết Collatz là đúng): “Cho trước số 1 cùng với hai phép toán * 2 và / 3, hãy sử dụng một cách hợp lý hai phép toán đó để biến số 1 thành một số nguyên dương X cho trước.” Ví dụ: X = 10 ta có biểu diễn 1 * 2 * 2 * 2 * 2 / 3 * 2 = 10. Giải thuật: Để biểu diễn X chia 2 trường hợp: Nếu X chẵn, thì tìm cách biểu diễn số X / 2 và viết thêm phép toán * 2 vào cuối. Nếu X lẻ, thì tìm cách biểu diễn số X * 3 + 1 và viết thêm phép toán / 3 vào cuối.
  • 14. 14 Đệ quy gián tiếp: Giả thiết Collatz void XuLySoLe(int X) //khi X lẻ { XuLySo(X * 3 + 1); printf(“ / 3”); } void XuLySoChan(int X) //khi X chẵn { XuLySo(X / 2); printf(“ * 2”); }
  • 15. 15 Đệ quy gián tiếp: Giả thiết Collatz //In ra cách biểu diễn số X void XuLySo(int X) { if (X == 1) printf(“%d”, X); else if (X % 2 == 1) XuLySoLe(X); else XuLySoChan(X); }
  • 16. 16 2.2. Thiết kế giải thuật đệ quy 2.2.1. Hàm N! 2.2.2. Dãy số Fibonacci 2.2.3. Chú ý
  • 17. 17 2.2.1. Hàm N! Mô tả đệ quy: 1 nếu N = 0 (phần neo) N! = N * (N - 1)! nếu N > 0 (phần đệ quy) Hàm đệ quy tính N! : long GT(int N) { if (N == 0) return 1; return N * GT(N – 1); }
  • 18. 18 3 đặc điểm đệ quy của hàm N! Đặc điểm: Đối chiếu với đặc điểm hàm đệ quy: Có lời gọi đến chính nó: hàm đệ quy GT(N) gọi đến hàm GT(N – 1). return N * GT(N – 1) Kích thước bài toán giảm dần: sau mỗi lần gọi đệ quy, giá trị của dữ liệu vào N giảm đi 1. Có trường hợp suy biến: là trường hợp N = 0. Khi đó, hàm GT(N) trả về giá trị 1 và đệ quy kết thúc. if (N == 0) return 1;
  • 19. 19 GT lặp tính N! Khái niệm: Phương pháp sử dụng vòng lặp để giải bài toán đệ quy gọi là khử đệ quy. Giải thuật mô tả phương pháp khử đệ quy gọi là giải thuật lặp. Đặc điểm: Ưu điểm: Thường hiệu quả hơn đệ quy do không phải thực hiện nhiều lần các thao tác: gọi hàm, cấp phát và giải phóng các biến cục bộ. Không bị tràn bộ nhớ stack như đệ quy do không phải lưu trữ các lời gọi trước. Nhược điểm: Việc tìm ra GT lặp thường khó khăn hơn nhiều GT đệ quy. Việc lập trình thường phức tạp.
  • 20. 20 GT lặp tính N! Mô tả không đệ quy: bài toán N! có thể mô tả theo cách không đệ quy như sau: N! = 1 * 2 * … * (N – 1) * N N! là tích của N số tự nhiên liên tiếp từ 1 đến N! Giải thuật lặp: long GT(int N) { long p = 1; for(int i = 2; i <= N; i++) p = p * i; return p; } Giải thuật lặp tính N! rất đơn giản!
  • 21. 21 Đánh giá độ phức tạp giải thuật Phân tích đánh giá độ phức tạp của giải thuật lặp tính N!: B1: Xác định phép toán tích cực: p = p * i; B2: Số lần thực hiện của phép toán tích cực là: 1 + 1 + … + 1 = N – 1 (lần) B3: Kết luận độ phức tạp của giải thuật: T(N) = O(N)
  • 22. 22 2.2.2. Dãy số Fibonacci Khái niệm: 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ỏ. Dãy số Fibonacci là mô hình của rất nhiều hiện tượng tự nhiên và cũng được sử dụng nhiều trong tin học. Bài toán: 1. Các con thỏ không bao giờ chết. 2. Hai tháng sau khi ra đời, 1 cặp thỏ mới sẽ sinh ra 1 cặp thỏ con gồm (1 đực, 1 cái). 3. Khi đã sinh con rồi thì cứ mỗi tháng tiếp theo chúng lại sinh ra được 1 cặp thỏ con mới. Yêu cầu: Từ 1 cặp thỏ mới ra đời thì đến tháng thứ N sẽ có bao nhiêu cặp thỏ?
  • 23. 23 Dãy số Fibonacci Diễn giải quá trình sinh sản của thỏ: Tháng thứ 1: 1 cặp (cặp ban đầu) Tháng thứ 2: 1 cặp (cặp ban đầu vẫn chưa sinh) Tháng thứ 3: 2 cặp (đã có thêm 1 cặp con) Tháng thứ 4: 3 cặp (cặp đầu vẫn sinh thêm) Tháng thứ 5: 5 cặp (cặp con bắt đầu sinh) Tháng thứ 6: 8 cặp (cặp con vẫn sinh tiếp) … Tháng thứ N: ? cặp Dãy số Fibonacci 1 1 2 3 5 8 … ?
  • 24. 24 Công thức tính số Fibonacci F(N) Tìm công thứ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 con thì: F(N) = 2 * F(N – 1) Do 2 tháng sau khi được sinh ra, thỏ mới sinh con, nên trong các cặp thỏ ở tháng thứ (N–1) chỉ có những cặp đã có ở tháng thứ (N – 2) mới sinh con ở tháng thứ N. Do đó số cặp thỏ ở tháng thứ N sẽ là: F(N) = F(N – 2) + F(N – 1) Mô tả đệ quy: tính F(N). 1 nếu N ≤ 2 //phần neo F(N) = F(N – 2) + F(N – 1) nếu N > 2 //phần đệ quy
  • 25. 25 GT đệ quy tính F(N) Hàm đệ quy tính F(N): long F(long N) { if (N <= 2) return 1; return F(N – 2) + F(N – 1); } 3 đặc điểm của hàm đệ quy: 1. Có lời gọi đến chính nó: return F(N – 2) + F(N – 1); 2. Kích thước bài toán giảm dần: N giảm thành N-1, N-2 3. Có trường hợp suy biến: F(1) = 1 và F(2) = 1 Chú ý: có 1 chi tiết hơi khác là trường hợp suy biến ứng với 2 giá trị: F(1) = 1 và F(2) = 1
  • 26. 26 Giải thuật lặp tính F(N) Giải thuật lặp: long F(long N) { if (N <= 2) return 1; Fib1 = 1; Fib2 = 1; for(long i = 3; i <= N; i++) { Fibn = Fib1 + Fib2; Fib1 = Fib2; Fib2 = Fibn; } return Fibn; }
  • 27. 27 Đánh giá độ phức tạp giải thuật Phân tích độ phức tạp của giải thuật lặp tính F(N): B1: Xác định phép toán tích cực: Fibn = Fib1 + Fib2; Fib1 = Fib2; Fib2 = Fibn; B2: Xác định số lần thực hiện của phép toán tích cực: 1 + 1 + … + 1 = N – 2 (lần) B3: Kết luận độ phức tạp của giải thuật lặp là: T(N) = O(N)
  • 28. 28 2.3. Một số dạng bài điển hình 2.3.1. Bài toán đếm 2.3.2. Bài toán liệt kê 2.3.3. Bài toán tối ưu
  • 29. 29 Một số dạng bài điển hình Bài toán đếm: trong tập các đối tượng cho trước, có bao nhiêu đối tượng thỏa mãn những điều kiện nhất định. Có bao nhiêu số nguyên tố không lớn hơn N? Bài toán liệt kê: trong tập các đối tượng cho trước, liệt kê cấu hình của tất cả những đối tượng thỏa mãn những điều kiện nhất định. Liệt kê các số nguyên tố không lớn hơn N? Bài toán tối ưu: trong tập các đối tượng cho trước, tìm cấu hình của đối tượng thỏa mãn những điều kiện nhất định và là tốt nhất theo một tiêu chí cụ thể. Tìm số nguyên tố lớn nhất trong các số nguyên tố không lớn hơn N?
  • 30. 30 2.3.1. Bài toán đếm Bài toán đếm: trong tập các đối tượng cho trước, có bao nhiêu đối tượng thỏa mãn những điều kiện nhất định. Ví dụ: Có bao nhiêu số nguyên tố không lớn hơn N? Có bao nhiêu xâu nhị phân độ dài N không chứa xâu ‘00’? Phương pháp giải: Công thức toán học + nguyên lý đếm cơ bản (cộng, nhân, bù trừ). Công thức truy hồi (phương trình truy hồi tuyến tính thuần nhất, đệ quy, quy hoạch động). Bài toán liệt kê: sử dụng phương pháp liệt kê để giải bài toán đếm, chỉ được sử dụng khi không tìm ra cách giải nào khác. Nhận xét: Bài toán đếm thường xuyên xuất hiện trong các bài thi OLP vì có nhiều khả năng cải tiến thuật giải để giảm thời gian chạy!
  • 31. 31 2.3.1. Bài toán đếm Bài toán: Xóa số (OLP Không chuyên 2012) Cho dãy số nguyên không âm a1, a2, …, an. Người ta tiến hành chọn ra 2 chỉ số i, j sao cho 1 ≤ i < j ≤ n và xóa khỏi dãy 2 số ai, aj để tổng giá trị các số còn lại trong dãy là số chẵn. Yêu cầu: Cho dãy số a1, a2, …, an. Hãy đếm số lượng cách chọn 2 chỉ số i, j thỏa mãn. Hai cách chọn khác nhau nếu tồn tại một chỉ số khác nhau. Dữ liệu: vào từ file văn bản DEL.INP: Dòng 1: chứa số nguyên n (n ≤ 106). Dòng 2: chứa n số nguyên không âm a1, a2, …, an (ai ≤ 109). Kết quả: đưa ra file văn bản DEL.OUT một số nguyên là số cách chọn 2 chỉ số thỏa mãn.
  • 32. 32 2.3.1. Bài toán đếm Ví dụ: Giải thích: Có 6 cách chọn 2 số (i, j) để xóa khỏi dãy để tổng còn lại là số chẵn. (1, 2) (1, 4) (2, 3) (2, 5) (3, 4) (4, 5) 65 1 2 3 4 5 DEL.OUTDEL.INP
  • 33. 33 2.3.1. Bài toán đếm B1: Xác định bài toán Vấn đề cần giải quyết: đếm số cách xóa các cặp (ai, aj) để tổng còn lại là số chẵn. Giả thiết: có n số nguyên a1, a2, …, an. Yêu cầu: số nguyên là số cách xóa. B2: Tìm cấu trúc dữ liệu n: kiểu số nguyên 4 byte. a: kiểu mảng 1 chiều của kiểu số nguyên 4 byte. Biến kết quả kq: kiểu số nguyên 8 byte. Chú ý: nếu mọi cách xóa 1 cặp (ai, aj) khỏi dãy số đều thỏa mãn điều kiện tổng còn lại là số chẵn thì số cách xóa tối đa (n = 106) là: n(n-1) / 2 = 5 * 1011 cách
  • 34. 34 2.3.1. Bài toán đếm B3: Tìm giải thuật GT 1: Ý tưởng: “vét cạn”, duyệt tất cả các phương án xóa số để tìm ra số cách kq. Đây chính là ý tưởng của bài toán liệt kê. Mô tả: kq = 0; sum = 0; //Tính tổng dãy số a for(i = 0; i < n; i++) sum = sum + a[i]; for(i = 0; i < n – 1; i++) for(j = i + 1; j < n; j++) { tong = sum – a[i] – a[j]; //Tổng còn lại if (tong % 2 == 0) kq = kq + 1; //Đếm } Đánh giá: Độ phức tạp GT 1 thuộc phân lớp N2.
  • 35. 35 2.3.1. Bài toán đếm GT 2: Ý tưởng: sử dụng “nguyên lý đếm”. Gọi sum là tổng các phần tử của dãy a[], x là số phần tử lẻ y = n – x là số phần tử chẵn. - Nếu sum chẵn thì phải xóa 2 số lẻ hoặc 2 số chẵn. Kết quả: kq = x(x-1)/2 + y(y-1)/2 - Nếu sum lẻ thì phải xóa 1 số lẻ và 1 số chẵn. Kết quả: kq = xy
  • 36. 36 2.3.1. Bài toán đếm Mô tả: //B1: Tính tổng dãy số a và số phần tử lẻ x sum = 0; x = 0; for(i = 0; i < n; i++) { sum = sum + a[i]; if (a[i] % 2 == 1) x = x + 1; } y = n – x; //Số phần tử chẵn //B2: Áp dụng nguyên lý đếm if(sum % 2 == 0) kq = x * (x – 1) / 2 + y * (y – 1) / 2; else kq = x * y; Đánh giá: Độ phức tạp GT 2 thuộc phân lớp N.
  • 37. 37 2.3.2. Bài toán liệt kê Bài toán liệt kê: trong tập các đối tượng cho trước, liệt kê cấu hình của tất cả những đối tượng thỏa mãn những điều kiện nhất định. Bài toán liệt kê cũng thuộc lớp bài toán đếm! Ví dụ: Liệt kê các số nguyên tố không lớn hơn N? Liệt kê các xâu nhị phân độ dài N không chứa xâu ‘00’? Phương pháp giải: Phương pháp sinh (generation): “hợp lý”, khó áp dụng. Thuật toán quay lui (backtracking algorithms): phổ biến. Nhận xét: Bài toán liệt kê hiếm khi xuất hiện trong các bài thi OLP vì có thời gian chạy lớn, khó có khả năng cải tiến thuật giải!
  • 38. 38 Phương pháp sinh Điều kiện áp dụng: Có thể xác định được 1 thứ tự trên tập các cấu hình cần liệt kê, cấu hình đầu tiên, cấu hình cuối cùng. Xây dựng được thuật toán từ 1 cấu hình chưa phải cấu hình cuối cùng, sinh ra cấu hình kế tiếp. Mô tả: <Xây dựng cấu hình đầu tiên>; do { <Liệt kê cấu hình hiện tại>; <Sinh cấu hình kế tiếp từ cấu hình hiện tại>; } while (<Chưa phải cấu hình cuối cùng>)
  • 39. 39 Phương pháp sinh Bài toán: Liệt kê các xâu nhị phân độ dài N Thứ tự: thứ tự từ điển (0, 1) tính từ phải sang trái. Cấu hình đầu tiên: 0 0 … 0 Cấu hình cuối cùng: 1 1 … 1 Phương pháp sinh: Xét xâu nhị phân từ phải sang trái, tìm số 0 đầu tiên. Tìm thấy: thay 0 bằng 1, cho các phần tử phía sau vị trí đó bằng 0 Không tìm thấy: là cấu hình cuối cùng. Kết thúc. Ví dụ: N = 5 Cấu hình hiện tại: 1 0 0 1 1 Tìm số 0 đầu tiên: 1 0 0 1 1 Thay 0 bằng 1: 1 0 1 1 1 Cấu hình kế tiếp: 1 0 1 0 0
  • 40. 40 Phương pháp sinh Bài toán: Liệt kê các tập con K phần tử Thứ tự: thứ tự từ điển (1, 2, …, N) tính từ phải sang trái. Cấu hình đầu tiên: 1 2 … K Cấu hình cuối cùng: N-K+1 N-K+2 … N Phương pháp sinh: Xét tập con từ phải sang trái, tìm phần tử đầu tiên (x[i]) chưa đạt giới hạn trên (N-K+i). Tăng x[i] lên 1, các pt sau (x[j]) bằng giới hạn dưới (x[j-1]+1). Không tìm thấy: là cấu hình cuối cùng. Kết thúc. Ví dụ: N = 9, K = 5 Cấu hình hiện tại: 1 3 7 8 9 Tìm phần tử đầu tiên chưa đạt giới hạn trên: 1 3 7 8 9 Tăng phần tử tìm được x[i] lên 1: 1 4 7 8 9 Cấu hình kế tiếp: 1 4 5 6 7
  • 41. 41 Phương pháp sinh Bài toán: Dãy số (OLP Không chuyên 2008) Một sinh viên Trường ĐH Kỹ thuật Công nghệ đang nghiên cứu về bài toán dãy số: tìm số An của dãy A0, A1, A2,…, trong đó A0 = 0, Ai là số nguyên dương nhỏ nhất lớn hơn Ai-1 và trong biểu diễn thập phân của Ai không chứa các chữ số trong biểu diễn thập phân của Ai với i ≥ 1. Như vậy các phần tử đầu tiên của dãy A là: 50 14 41 13 …3022109876543210A[i] …1211109876543210i
  • 42. 42 Phương pháp sinh Yêu cầu: Cho số tự nhiên n. Hãy tìm An. Dữ liệu: vào từ file văn bản NUMSEG.INP trong đó chứa duy nhất số n (0 ≤ n ≤ 500). Kết quả: ghi ra file văn bản NUMSEG.OUT giá trị An. Ví dụ: 00 3012 91127 NUMSEG.OUTNUMSEG.INP
  • 43. 43 Thuật toán quay lui Ý tưởng: Xây dựng cấu hình liệt kê x[1..n] bằng cách thử tất cả các khả năng của từng phần tử x[i]. Cho x[1] nhận lần lượt các giá trị có thể. Với mỗi x[1]: Cho x[2] nhận lần lượt các giá trị có thể. Với mỗi x[2]: • … Cho x[n] nhận lần lượt các giá trị có thể. Với mỗi x[n], ta có 1 cấu hình x[1..n] Nhận xét: Ý tưởng của thuật toán quay lui là “duyệt toàn bộ”. Có thể giải được hầu hết các bài toán tổ hợp. Chỉ sử dụng thuật toán quay lui để giải các bài toán đếm, tối ưu khi không còn lựa chọn nào khác.
  • 44. 44 Thuật toán quay lui Mô tả: void try(i) //Cho x[i] nhận lần lượt các giá trị có thể { for (<Mọi giá trị V có thể gán cho x[i]>) { x[i] = V; if (i == n) <Thông báo cấu hình tìm được>; else try(i+1); //Gọi đệ quy để chọn x[i+1] } }
  • 45. 45 Thuật toán quay lui Điều kiện áp dụng: Tìm được tập giá trị có thể của 1 phần tử x[i] bất kỳ trong cấu hình x[1..n]. Đối với các bài toán tổ hợp, điều kiện này thường dễ dàng tìm được! Bài toán: Liệt kê xâu nhị phân độ dài N: tập giá trị của 1 phần tử x[i] trong xâu là (0, 1).
  • 46. 46 2.3.3. Bài toán tối ưu Bài toán tối ưu: trong tập các đối tượng cho trước, tìm cấu hình của đối tượng thỏa mãn những điều kiện nhất định và là tốt nhất theo một tiêu chí cụ thể. Ví dụ: Tìm số nguyên tố lớn nhất trong các số nguyên tố ≤ N? Bài toán Mật độ giao thông – OLP 2012: tìm độ lệch của hai đoạn đường có tình trạng giao thông giống nhau nhất? Phương pháp giải: rất đa dạng Phương pháp quy hoạch động (dynamic programming). Thuật toán tham lam (greedy algorithms). Thuật toán quay lui: kỹ thuật nhánh cận Nhận xét: Bài toán tối ưu thường xuyên xuất hiện trong các bài thi OLP, cũng như trong các bài toán thực tế
  • 47. 47 2.4. Câu hỏi ôn tập 1. Hàm Ackermann: Cho mô tả đệ quy: N + 1 nếu M = 0 Acker(M, N) = Acker(M – 1, 1) nếu N = 0 Acker(M – 1, Acker(M, N – 1)) còn lại (Hàm Ackermann có đặc điểm là giá trị tăng rất nhanh khi đối số M, N tăng, M và N là các giá trị nguyên) a) Chỉ rõ phần neo và phần đệ quy trong mô tả. b) Minh họa quá trình tìm Acker(1, 2). c) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3 đặc điểm của hàm đệ quy.
  • 48. 48 2.4. Câu hỏi ôn tập 2. Bài toán Fibonacci: Tìm phần tử thứ N trong dãy số Fibonacci. a) Nêu mô tả đệ quy và chỉ rõ phần neo và phần đệ quy. b) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3 đặc điểm của hàm đệ quy. c) Minh họa quá trình tìm F(5). d) Viết hàm tính giá trị của hàm bằng giải thuật lặp. Phân tích đánh giá giải thuật trong trường hợp trung bình.
  • 49. 49 2.4. Câu hỏi ôn tập 3. Bài toán Ước số chung lớn nhất bằng phép chia: Tìm USCLN(A, B) với A và B là các số tự nhiên không đồng thời bằng 0. a) Nêu mô tả đệ quy và chỉ rõ phần neo và phần đệ quy. b) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3 đặc điểm của hàm đệ quy. c) Minh họa quá trình tìm USCLN(234, 198). d) Viết hàm tính giá trị của hàm bằng giải thuật lặp. Phân tích đánh giá giải thuật trong trường hợp tốt nhất.
  • 50. 50 2.4. Câu hỏi ôn tập 4. Bài toán Ước số chung lớn nhất bằng phép trừ: Tìm USCLN(A, B) với A và B là các số tự nhiên không đồng thời bằng 0. a) Nêu mô tả đệ quy và chỉ rõ phần neo và phần đệ quy. b) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3 đặc điểm của hàm đệ quy. c) Minh họa quá trình tìm USCLN(126, 72).
  • 51. 51 2.4. Câu hỏi ôn tập 5. Hàm tổ hợp: Cho mô tả đệ quy: 1 nếu K = 0 hoặc K = N C(N, K) = C(N – 1, K) + C(N – 1, K – 1) nếu 0 < K < N a) Chỉ rõ phần neo và phần đệ quy trong mô tả. b) Minh họa quá trình tìm C(5, 2). c) Viết 1 hàm đệ quy tính giá trị của hàm này và chỉ rõ 3 đặc điểm của hàm đệ quy. d) Viết hàm tính giá trị của hàm bằng giải thuật lặp theo công thức sau: K!K)!(N N! K)C(N, − =