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

Định dạng
Số trang 8
Dung lượng 50 KB

Nội dung

Đệ quy cỡ nhỏ

Đệ quy nhớĐỗ Đức ĐôngBài toán 1: Số FibonacciXé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)= 1Fib(2)= 1Fib(n)= Fib(n-1)+Fib(n-2) với n>2Phâ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 Fib(n-1)và Fib(n-2). Bài toán Fib(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 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;BeginIf 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;BEGINNhap;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 thể tự giải bài này.Bài 3: Phân trang (Đề thi chọn đội tuyển quốc gia 99 ) Văn bản là một dãy gồm N từđánh số từ 1 đến N. Từ thứ i độ dài là wi (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)- Dòng thứi trong số N dòng tiếp theo chứa số nguyên dương wi (wi<=L),i=1, 2, , NKế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ừ 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)} 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 trang ptj vớij=1, 2, ., i. Ta thấy các bài toán con chính là tìm hệ số phạt (nhỏ nhất)của 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ừ 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;Beginassign(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} h[0]:=0; {giải bài toán con nhất là không từ nào}End;Function maxso(u,v:integer):integer;Beginif 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;Beginif h[i]=-1 then {chưa được làm}begins:=w[i];j:=i;h[i]:=maxint;while (s<=L)and(j>0) dobeginmin:=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<> beginh[i]:=min;tr[i]:=j;end;dec(j); s:=s+w[j];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;beginif tr[i]>0 thenbegininc(sd);viet(tr[i]-1);for j:=tr[i] to ido write(f,j,#32);writeln(f);endelse writeln(f,sd);end;Beginsd:=0;assign(f,fo); rewrite(f);write(f,kq,#32);viet(n);close(f);End;BEGINdocf;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 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à 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 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, ., nCho 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 -> x34) BA ->x4 5)BB -> x5 6) BC -> x67) CA ->x7 8)CB -> x8 9) CC -> x9trong đó xithuộc {A,B,C}, i=1,2, ,9Cầ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ự wKế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 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ự. . Đệ quy có nhớĐỗ Đức ĐôngBài toán 1: Số FibonacciXét dãy số Fibonacci: 1, 1,2,. bài toán con chính là tìm hệ số phạt (nhỏ nhất)của 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

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

TỪ KHÓA LIÊN QUAN

w