1. Trang chủ
  2. » Công Nghệ Thông Tin

Đệ quy cỡ nhỏ

8 729 13
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Đệ quy có nhớ
Tác giả Đỗ Đức Đông
Trường học Trường Đại Học
Thể loại bài luận
Định dạng
Số trang 8
Dung lượng 50 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Đệ quy cỡ nhỏ

Trang 1

Đệ quy có nhớ

Đỗ Đức Đông

Bài toán 1: Số Fibonacci

Xét dãy số Fibonacci: 1, 1,2, 3, 5, 8, 11, ; trong đó số đứng sau bằng tổng hai số đứng trước nó Hãytìm số Fibonacci thứ n.

Fib(1)= 1

Fib(2)= 1

Fib(n)= Fib(n-1)+Fib(n-2) với n>2

Phân tích bài toán:Việc giải bài toán lớn Fib(n) tương đương với việc giải hai bài toán

con 1)và 2) Bài toán 1) lại được chia ra làm hai bài toán con Fib(n-2)và Fib(n-3) Như vậy, bài toán Fib(n-2) được gặp lại Và tiếp tục như vậy, tacó:

Fib[n] = Fib[n-1] + Fib[n-2] =(Fib[n-2]+Fib[n-3])+Fib[n-2] =

Lời giải: Ta sẽdùng một mảng một chiều F[1 N] phần tử thứ k sẽ là số Fib thứ k Ban

đầu tagán các phần tử của mảng F đều bằng -1 (đánh dấu để phân biệt bài toán đượcgiải hay chưa) Giải hai bài toán con nhỏ nhất F[1]:=1 và F[2]:=1 Khi giải bàitoán Fib(k) ta kiểm tra xem bài toán này đã được giải chưa (thể hiện bằngF[k]=-1, hay khác -1) Nếu bài toán chưa được giải (F[k]=-1) thì ta sẽ tínhFib(k) nếu không ta sẽ sử dụng kết quả bài toán Fib(k) là F[k]

Chương trình dưới đây khá gọn,dễ hiểu và rất hiệu quả

Uses crt;

Const max = 20;

Var F : array[1 max]oflongint;

N : integer;

Procedure Nhap;

Var k :integer;

Begin

Trang 2

Write(?Nhap N:?); readln(n);

For k:=1 to n do F[k]:=-1; {tất cả các bài toán đều chưa được giải}

F[1]:=1;F[2]:=1; {giải hai bài toán con nhỏ nhất}

End;

FunctionFib(k:integer):longint;

Begin

If F[k]=-1 then { Nếu bài toán con này chưa được giải}

F[k]:=Fib(k-1)+Fib(k-2); {chia ra làm 2 bài toán con}

Fib:=F[k]; {lấy kết quả}

End;

BEGIN

Nhap;

Writeln('Fibonacci(', n ,')='), Fib(n));

Readln;

END

Bài toán 2: Tính tổ hợp chập k của N phần tử C(k,n)

Phân tích bài toán:

C[k,n] = C[k,n-1] + C[k-1,n-1]= (C[k,n-2] + C[k-1,n-2]) +(C[k-1,n-2] + C[k-2,n-2]) = Như vậy C[k-1,n-2] được tínhlại Cứ tiếp tục khai triển ta sẽ thấy các bài toán con khác cũng sẽ lặp lạinhiều lần

Gợi ý: Dùng mảng2 chiều C[1 k,1 N] Phần tử thứ C[k,n] sẽ là kết quả của tổ hợp chập k

của Nphần tử

Các bạn có thể tự giải bài này

Bài 3: Phân trang (Đề thi chọn đội tuyển quốc gia 99 )

Trang 3

Văn bản là một dãy gồm N từđánh số từ 1 đến N Từ thứ i có độ dài là w i (i=1, 2, N) Phântrang là một cách xếp lần lượt các từ của văn bản vào dãy các dòng, mỗi dòng cóđộ dài L, sao cho tổng độ dài của các từ trên cùng một dòng không vượt quá L.Ta gọi hệ số phạt của mỗi dòng trong cách phân trang là hiệu số (L-S), trong đóS là tổng độ dài của các từ xếp trên dòng đó Hệ số phạt của cách phân trang làgiá trị lớn nhất trong số các

hệ số phạt của các dòng.

Yêu cầu: Tìmcách phân trang với hệ số phạt nhỏ nhất.

Dữ liệu vào từ tệp văn bảnPTRANG.INP

- Dòng 1chứa 2 số nguyên dương N, L (N<=4000, L<=70)

Kết qủa ghi ra file văn bảnPTRANG.OUT

- Dòng 1ghi 2 số P,Q theo thứ tự là hệ số phạt và số dòng theo cách phân trang tìm được

- Dòng thứi trong số Q dòng tiếp theo ghi chỉ số của các từ trong dòng thứ i của

cáchphân trang.

Ví dụ:

Lời giải:

Xét bài toán với i từ đầu tiên(các từ có số thứ tự từ 1 tới i) Ta gọi cách phân trang ptj là

cáchphân trang tối ưu từ thứ 1 đến từ thứ j vào mộtsố dòng và phân trang từ thứ j+1 đến

từ thứ i vào một dòng tiếp theo (với điều kiện tổng chiều dài các từ từ j+1 tớii không lớn

hơn L hay S = Wj+1 + Wj+2 + + Wi <=L)

Như vậy hệ số phạt nhỏ nhất củacách phân trang i từ này là:

MAX {hệ số phạt của cách phân trang tối ưu từ thứ 1 đến từ thứ jvào một số dòng,

hệ số phạt củacác từ thứ j+1 đến từ thứ i vào một dòng(=L-S)}

Trang 4

Vậy cách phân trang tối ưu i từđầu chính là cách phân trang tốt nhất củacác cách phân

cách phân trang tối ưu i từ đầu với i = 1, 2, , N Hệ số phạt nhỏ nhấtcủa cách phân trang

N từ chính là kết quả của cách phân trang tối ưu N từ đầu

Ta sẽ dùng một mảng h[0 n],h[i] - là hệ số phạt (nhỏ nhất) của cách phân trang tối ưu nhất các từ có sốthứ tự từ 1 đến i

Chương trình sau thể hiện thuậttoán trên

{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R+,S+,T-,V+,X+}

{$M 65000,0,655360} {mở rộngStack}

Uses crt;

Const maxn = 4000;

fi = 'ptrang.inp';

fo = 'ptrang.out';

Var h, tr, w : array[0 maxn] of integer;

n, L, kq :integer;

Procedure docf;

var f : text;

k : integer;

Begin

assign(f,fi);

reset(f);

readln(f,n,L);

for k:=1 to n do read(f,w[k]);

close(f);

for k:=1 to n do h[k]:=-1; {tất cả các bài toán đều chưa giải}

Trang 5

h[0]:=0; {giải bài toán con nhất là không có từ nào}

End;

Function maxso(u,v:integer):integer;

Begin

if u>v then maxso:=u else maxso:=v;

End;

Function hsp(i:integer):integer;{hệsố phạt tối ưu nhất của cách phân trang các từ 1 đến i} var j,s,min : integer;

Begin

if h[i]=-1 then {chưa được làm}

begin

s:=w[i];

j:=i;

h[i]:=maxint;

while (s<=L)and(j>0) do

begin

min:=maxso(hsp(j-1),L-s);{từ 1 đến j-1 làm 1 nhómdòng,j đến i làm 1 dòng}

if min<>

begin

h[i]:=min;

tr[i]:=j;

end;

dec(j);

Trang 6

end;

end;

hsp:=h[i];{lấy kết quả}

End;

Procedure ghif;

var f : text;

sd :integer;

procedure viet (i: integer);{lần kết quả} var j : integer;

begin

if tr[i]>0 then

begin

inc(sd);

viet(tr[i]-1);

for j:=tr[i] to ido write(f,j,#32);

writeln(f);

end

else writeln(f,sd);

end;

Begin

sd:=0;

assign(f,fo);

Trang 7

write(f,kq,#32);

viet(n);

close(f);

End;

BEGIN

docf;

kq:=hsp(n);{đi tìm kết quả bài toán}

ghif;

END

Nhận xét :

+ Để giải bài toán bằngphương pháp "Đệ qui có nhớ" ta phải thực hiện các bước sau:

- Bước 1: Chia bài toán thànhcác bài toán con.

- Bước 2: Tìm công thức truyhồi.

- Bước 3: Tối ưu công thức (giảmcác chiều của bài toán).

- Bước 4: Lưu các bài toán nhỏ,giải các bài toán con nhỏ nhất.

- Bước 5: Giải bài toán lớn dựavào các bài toán con.

+ Phương pháp trên giải đượcrất nhiều bài toán về các vấn đề sau:

- Tìmsố cấu hình của một dạng (áp dụng giải các bài toán thứ tự từ điển)

- Cácbài toán tối ưu

+ Hạn chế của phương pháp là có thể bị tràn Stack (do đệ qui quá sâu)nên khi giải các bạn hãy mở rộng Stackhoặc dùng khử đệ qui.

Bài tập tự giải:

1 Tìm số cách phân tích số tự nhiên N thành tổng các số tự nhiên x1,x2, sao cho

Trang 8

N = x1 +x2 + với x1 > x 2 > > 0 (n <= 50)

2 Biến đổi một xâu về một ký tự định trước.

Cho xâu ký tự U = u1u2 untrong đó ui thuộc các ký tự {A,B,C}, i = 1, 2, , n

Cho các phép biến đổi sau đây(đánh số từ 1 đến 9) cho phép thay thế hai ký tự liên tiếp nhau trong xâu đãcho cho bởi một ký tự:

1) AA ->x1 2)AB -> x2 3) AC -> x3

4) BA ->x4 5)BB -> x5 6) BC -> x6

7) CA ->x7 8)CB -> x8 9) CC -> x9

trong đó xithuộc {A,B,C}, i=1,2, ,9

Cần tìm cách áp dụng lần lượtcác phép biến đổi đã cho để chuyển xâu U về một ký tự định trước w thuộc {A, B,C}

Dữ liệu vào cho trong fileXAU.INP

- Dòng 1 làxâu U

- Dòng 2 làxâu x1x2 x9

- Dòng 3 làký tự w

Kết quả ra file XAU.OUT

- Dòng 1 làsố lượng phép biến đổi M cần áp dụng để chuyển xâu U thành w,dòng này ghi

0 nếukhông biến đổi được

- Nếu có thểbiến đổi thì dòng thứ i trong số m dòng tiếp theo ghi số thứ tự của phép biếnđổi cần sử dụng và chỉ số của 2 phần tử liên tiếp nhau trong dãy đang biến đổicần phải thay thế bằng một ký tự

Ngày đăng: 07/09/2012, 11:40

TỪ KHÓA LIÊN QUAN

w