1. Trang chủ
  2. » Giáo án - Bài giảng

BÀI TOÁN XÂU TRONG CỰC ĐẠI VÀ LỜI GIẢI

14 1,1K 7

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 14
Dung lượng 538,5 KB

Nội dung

Xâu con: S là xâu con của T nếu S nhận được bằng cách xoá đi một số ký tự nào đó trong T. Ví dụ: ‘EAC’ là xâu con của ‘CEAEEC’ Xâu con chung: Nếu xóa một số ký tự của hai xâu thì hai xâu con còn lại của chúng bằng nhau Ví dụ: S1=‘ABCDAE’ và S2=‘XYACADK’ có xâu ‘ACD’ là xâu con chung có độ dài cực đại. Bài toán đặt ra: Cho 2 xâu A, B. Tìm một xâu S là xâu con chung của A và B có độ dài cực đại. - Input: File Input.doc có cấu trúc: + Dòng thứ nhất chứa xâu A + Dòng thứ hai chứa xâu B - Output: File output.doc có cấu trúc: Nếu bài toán vô nghiệm thì ghi số 0, ngược lại ghi như sau: + Dòng thứ nhất ghi số K là số kí tự của xâu chung S + Dòng thứ hai là xâu S gồm K kí tự. BÀI GIẢI: B1: Phân tích bài toán Gọi M= length(A); N= length(B); * Cần xây dựng mảng L[0..M, 0..N] với ý nghĩa: L[I,j] là độ dài của xâu chung dài nhất của 2 xâu: A[0..i] và B[0..j]. * Bài toán ban đầu là: L[M,N]. Đương nhiên nếu một xâu là rỗng (số kí tự là 0) thì xâu con chung cũng là rỗng, vì vậy: L[0,j]=0 ∀ j, j=1..N. L[i,0]=0 ∀ i, i=1..M. B2: Giải pháp đệ quy

1. BÀI TOÁN XÂU TRONG CỰC ĐẠI Xâu con: S là xâu con của T nếu S nhận được bằng cách xoá đi một số ký tự nào đó trong T. Ví dụ: ‘EAC’ là xâu con của ‘CEAEEC’ Xâu con chung: Nếu xóa một số ký tự của hai xâu thì hai xâu con còn lại của chúng bằng nhau Ví dụ: S1=‘ABCDAE’ S2=‘XYACADK’ có xâu ‘ACD’ là xâu con chung có độ dài cực đại. Bài toán đặt ra: Cho 2 xâu A, B. Tìm một xâu S là xâu con chung của A B có độ dài cực đại. - Input: File Input.doc có cấu trúc: + Dòng thứ nhất chứa xâu A + Dòng thứ hai chứa xâu B - Output: File output.doc có cấu trúc: Nếu bài toán vô nghiệm thì ghi số 0, ngược lại ghi như sau: + Dòng thứ nhất ghi số K là số kí tự của xâu chung S + Dòng thứ hai là xâu S gồm K kí tự. BÀI GIẢI: B1: Phân tích bài toán Gọi M= length(A); N= length(B); * Cần xây dựng mảng L[0 M, 0 N] với ý nghĩa: L[I,j] là độ dài của xâu chung dài nhất của 2 xâu: A[0 i] B[0 j]. * Bài toán ban đầu là: L[M,N]. Đương nhiên nếu một xâu là rỗng (số kí tự là 0) thì xâu con chung cũng là rỗng, vì vậy: L[0,j]=0 ∀ j, j=1 N. L[i,0]=0 ∀ i, i=1 M. B2: Giải pháp đệ quy Với M ≥ I > 0 N ≥ j > 0 thì: + Nếu A[i]=B[j] thì L[I,j] = L[i-1,j-1] +1 + Nếu A[i] < > B[j] thì: * Nếu A[i] trong B[1 j] thì nó chỉ thuộc B[1 j-1] nên L[I,j]=L[I,j-1] * Nếu B[j] trong A[1 i] thì nó chỉ thuộc A[1 i-1] nên L[I,j]=L[I-1,j] Vì vậy: L[I,j] được tính theo công thức truy hồi sau: L[I,j] = Max{L[I,j-1], L[i-1,j], L[i-1,j-1] + X} (với X=0 nếu A[i] < > B[j]; X=1 nếu A[i] = B[j]). B3: Lập bảng PROCEDURE LAPBANG; VAR I,J: BYTE; BEGIN FOR I:=1 TO M DO L[I,0]:=0; FOR J:=1 TO N DO L[0,J]:=0; FOR I:=1 TO M DO FOR J:=1 TO N DO BEGIN IF A[I] = B[J] THEN L[I,J]:= L[I-1,J-1] +1 ELSE L[I,J]:=MAX(L[I,J-1],L[I-1,J]); END; END; B4: Tổng hợp kết quả Procedure TongHop; Begin S:=’’; While (i>0) and (j>0) Do If L[i,j]=L[i,j-1] then j:=j-1 Else If L[i,j]=L[i-1,j] then i:=i-1 Else Begin S:=A[i]+S; i:=i-1; j:=j-1; End; End; * CÀI ĐẶT: USES CRT; CONST FI='INPUT.DOC'; FO='OUTPUT.DOC'; VAR F: TEXT; M,N: BYTE; A,B,S: STRING; CH:CHAR; L: ARRAY[0 100,0 100] OF BYTE; PROCEDURE DOC_INPUT; VAR F: TEXT; BEGIN M:=0; N:=0;A:=''; B:=''; ASSIGN(F,FI); RESET(F); WHILE NOT EOLN(F) DO BEGIN INC(M); READ(F,CH); A:=A+CH; END; READLN(F); WHILE NOT EOLN(F) DO BEGIN INC(N); READ(F,CH); B:=B+CH; END; CLOSE(F); END; FUNCTION MAX(I,J: INTEGER) : INTEGER; VAR P: INTEGER; BEGIN IF I>J THEN MAX:=I ELSE MAX:=J; END; PROCEDURE LAPBANG; VAR I,J: BYTE; BEGIN FOR I:=1 TO M DO L[I,0]:=0; FOR J:=1 TO N DO L[0,J]:=0; FOR I:=1 TO M DO FOR J:=1 TO N DO BEGIN IF A[I] = B[J] THEN L[I,J]:= L[I-1,J-1] +1 ELSE L[I,J]:=MAX(L[I,J-1],L[I-1,J]); END; END; PROCEDURE TONGHOP; VAR F: TEXT; I,J: INTEGER; BEGIN ASSIGN(F,FO); REWRITE(F); IF L[M,N]= 0 THEN BEGIN WRITE(F,0); CLOSE(F);HALT; END ELSE BEGIN WRITELN(F,L[M,N]); I:=M; J:=N; S:=''; WHILE (I>0) AND (J>0) DO IF L[I,J] = L[I,J-1] THEN DEC(J) ELSE IF L[I,J]=L[I-1,J] THEN DEC(I) ELSE BEGIN S:=A[I]+S; DEC(I); DEC(J); END; END; WRITE(F,S); CLOSE(F); END; BEGIN CLRSCR; DOC_INPUT; LAPBANG; TONGHOP; END. 2. BÀI TOÁN DU LỊCH * Phát biểu bài toán: Một người đi từ thành phố 0 đến thành phố n có thể đi qua n-1 thành phố khác 1, 2, . . ., n-1, theo lộ trình: 0 -> i 1 -> i 2 . . . -> i k -> n, trong đó: 0 < i 1 < i 2 < i k < n. Giá vé xe đi từ thành phố i đến thành phố j là c[i,j]. Tìm một lộ trình từ thành phố 0 đến thành phố n sao cho tổng chi phí về giá vé đạt cực tiểu. *Bước 1: Phân tích bài toán - Gọi ρ(s) là bài toán du lịch, với: (thành phố xuất phát là 0) s Î N: là thành phố cần đến. ( Bài toán ban đầu là ρ(n)) - Các giá trị cần tìm: l[s]: chi phí nhỏ nhất để đi từ 0 → s của bài toán ρ(s) u[s]: đỉnh kế cuối trên đường đi từ 0 → s của bài toán ρ(s) * Bước 2: Giải pháp đệ quy - Nếu s=0 thì: • l[0] = 0 • u[0] = -1 - Nếu s≠0 (0<s) thì: • l[s] = min (l[k] + c[k,s]) (0 ≤ k<s) = l[k’] + c[k’,s] • u[s] = k’ * Bước 3: Lập bảng Procedure Lapbang; Begin for s:= 0 to n do if (s= 0) then Tính l[0] u[0] else Tính l[s] u[s] End; Cụ thể: Procedure lapbang; var s,k,ke: byte; min,tam: integer; begin for s:=0 to n do if (s=0) then begin l[0]:=0; u[0]:=-1; end else begin ke:=0; min:=max; for k:=r to s-1 do if (c[k,s]>0) then begin tam:=l[k]+c[k,s]; if (tam<min) then begin ke:=k; min:=tam; end; end; l[s]:=min; u[s]:=ke; end; end;  Độ phức tạp tính toán: O(n 2 ) * Bước 4: Tổng hợp kết quả Procedure Tonghop; Begin i :=1; s := n; x[1] := s; while s ≠ 0 do begin i := i + 1; s := u[s]; x[i]:= s; end; End; * Chương trình: const max=32767; var c:array[0 100,0 100] of integer; u,l, x:array[1 100] of integer; n:byte; procedure docfile; var f:text; i,j:byte; begin assign(f,'input.txt');reset(f); readln(f,n); for i:=0 to n do for j:=0 to n do read(f,c[i,j]); close(f); end; procedure lapbang; var s,k,ke:byte; min,tam:integer; begin for s:=0 to n do if (s=0) then begin l[0]:=0; u[0]:=-1; end else begin ke:=0; min:=max; for k:=0 to s-1 do if (c[k,s]>0) then begin tam:=l[k]+c[k,s]; if (tam<min) then begin ke:=k; min:=tam; end; end; l[s]:=min; u[s]:=ke; end; end; procedure tonghop; var i,s,dem:byte; begin s:=n; x[1]:=s; i:=2; while (s<>0) do begin x[i]:=u[s]; s:=x[i]; i:=i+1; end; if (s<>0) then write('Khong co duong di') else begin write('Duong di voi chi phi nho nhat: '); for dem:=i-1 downto 1 do write(' ',x[dem]:2); writeln; writeln('Chi phi nho nhat: ',l[n]); end; end; BEGIN docfile; lapbang; tonghop; readln; END. 3. BÀI TOÁN SINH VIÊN ÔN THI a. Phát biểu bài toán Một sinh viên còn m ngày để ôn thi n môn. Theo kinh nghiệm của anh ta, nếu ôn môn j trong i ngày thì được điểm là a[i,j]. Giả sử cho biết các a[i,j] (với a[i,j] ≤ a[i+1,j]). Tìm bộ x[j] (số ngày ôn môn j, j = 1 n) sao cho Σx[j] = m sinh viên đạt tổng điểm lớn nhất. (Σa[x[j], j] → max).  Input: - m ∈ N: số ngày ôn thi - n ∈ N* : số môn ôn thi - a[i,j] ∈ R: điểm đạt được khi ôn thi môn j trong i ngày. (i=0 m, j=1 n)  Output: x[j]: số ngày ôn thi môn j (j=1 n) sao cho Σx[j]=n Σa[x[j],j] đạt max b. Phân tích bài toán Gọi P(r,s) là bài toán ôn thi, với: • r ∈N là số ngày ôn thi. • s ∈ N* là số môn ôn thi. (Bài toán ban đầu là P(m,n)) Các giá trị cần tìm: • diem[r,s]: tổng điểm lớn nhất Σa[x[j],j] của bài toán P(r,s). • ngay[r,s]: số ngày ôn thi môn s (tức là x[s]) của bài toán P(r,s). c. Giải pháp đệ quy • Trường hợp suy biến: s=1 (chỉ có 1 môn) - ngay[r,s]=ngay[r,1]=r (vì chỉ có 1 môn nên tận dụng hết tất cả r ngày để ôn thi) - diem[r,s]=diem[r,1]=a[r,1] • Trường hợp đệ quy (s>1): - diem[r,s] = max (a[k,s]+diem[r-k,s-1]) (k: số ngày ôn, 0≤k≤ r thi môn s) = a[k’,s]+diem[r-k’,s-1] Trong đó:  a[k,s] là điểm thi môn thứ s với k ngày ôn  diem[r-k,s-1] là tổng điểm tối ưu của s-1 môn thi với r-k ngày ôn  k' là số ngày ôn thi môn s mà tại đó diem[r,s] có giá trị tối ưu - ngay[r,s] = k’ d. Lập bảng Thủ tục LapBang như sau: Procedure LapBang; Begin For r:=0 to m do For s:=1 to n do If s=1 then begin diem[r,s]:=a[r,s]; ngay[r,s]:=r; end Else Tinhdiem_ngay; {Tinh diem[r,s] ngay[r,s]} End; Độ phức tạp tính toán: O(n.m 2 ) Trong đó: Procedure Tinhdiem_ngay; Var tam, k,k1:integer; Begin k1:=0; tam:=a[0,s]+diem[r,s-1]; For k:=1 to r do if tam<a[k,s]+diem[r-k,s-1] then begin tam:=a[k,s]+diem[r-k,s-1]; k1:=k; [...]...end; diem[r,s]:=tam; ngay[r,s]:=k1; End; e Tổng hợp kết quả Procedure TongHop; Begin r:=m; For s:=n downto 1 do begin x[s]:=ngay[r,s]; r:=r-x[s]; end; End; • Độ phức tạp tính toán: O(n) f Cài đặt chương trình (bằng Turbo Pascal) Program Sinh_vien_on_thi; Uses crt; Type Mang=array[1 50,1 50] of integer; Var i,j,r,s,k,n,m,tam,k1:Integer; A,ngay,diem:Mang; X:Array[1 2500] of integer;

Ngày đăng: 27/05/2014, 19:36

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w