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
Tài liệu đã được kiểm tra trùng lặp

Đ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

Tiêu đề Bài toán xâu trong cực đại và lời giải
Trường học University of Science and Technology
Chuyên ngành Computer Science
Thể loại bài tập
Năm xuất bản 2023
Thành phố Hanoi
Định dạng
Số trang 14
Dung lượng 538,5 KB

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

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

Trang 1

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’ 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

Với M ≥ I > 0 và 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

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]);

Trang 2

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;

Trang 3

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

Trang 4

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.

Trang 5

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 và có thể đi qua n-1 thành phố khác 1, 2, , n-1, theo lộ trình: 0 -> i1 -> i2 -> ik -> n, trong đó: 0 < i1 < i2 <

ik < 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] và u[0]

else Tính l[s] và u[s]

End;

Cụ thể:

Procedure lapbang;

var s,k,ke: byte;

min,tam: integer;

Trang 6

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(n2 )

* 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;

Trang 7

* 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;

Trang 8

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.

Trang 9

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 và 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 và Σ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’

Trang 10

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] và ngay[r,s]} End;

Độ phức tạp tính toán: O(n.m2)

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;

Trang 11

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;

f:Text;

ch:Char;

{Tao file Input.txt de luu du lieu}

Procedure NhapDL;

Begin

Assign(f,'Input.txt');

Rewrite(f);

Write('Nhap so ngay on thi: ');

Readln(m);

Writeln(f,m);

Write('Nhap so mon on thi: ');

Readln(n);

Writeln(f,n);

For i:=0 to m do

begin

For j:=1 to n do

begin

Trang 12

Write('Nhap diem a[',i,',',j,']= ');

Readln(a[i,j]);

Write(f,a[i,j]:5,' ');

end;

Writeln(f);

end;

Close(f);

End;

{Doc du lieu tu file Input.txt luu vao bien m,n va mang A} Procedure DocDL;

Begin

Assign(f,'Input.txt');

Reset(f);

Readln(f,m);

Readln(f,n);

For i:=0 to m do

begin

For j:=1 to n do

Read(f,a[i,j]);

Readln(f);

end;

Close(f);

End;

{Buoc lap bang}

Procedure Lap_bang;

Begin

DocDL;

For r:=0 to m do

begin

For s:=1 to n do

begin

If s=1 then

begin

ngay[r,1]:=r;

diem[r,1]:=A[r,1];

end

Else

begin

tam:=a[0,s]+diem[r,s-1];

k1:=0; {k1 la k'}

For k:=1 to r do

If tam<a[k,s]+diem[r-k,s-1] then

begin

Trang 13

tam:=a[k,s]+diem[r-k,s-1];

k1:=k;

end;

diem[r,s]:=tam;

ngay[r,s]:=k1;

end;

Write(diem[r,s]:5,'/',ngay[r,s],' ');

end;

Writeln;

end;

End;

{Buoc tong hop ket qua}

Procedure Tong_hop;

Begin

r:=m;

For s:=n downto 1 do

Begin

X[s]:=ngay[r,s];

Writeln('So ngay on thi mon ',s,' tot nhat la: ',X[s]); r:=r-X[s];

End;

End;

{In du lieu vua doc ra tu file Input.txt}

Procedure HienthiDL;

Begin

DocDL;

Writeln('So ngay on thi: ',m);

Writeln('So mon on thi: ',n);

Writeln('So diem: ');

For i:=0 to m do

begin

For j:=1 to n do

Write(a[i,j]:5);

Writeln;

end;

End;

BEGIN

Clrscr;

Write('Ban co muon tao moi du lieu khong? (c/k) '); Readln(ch);

If upcase(ch)<>'K' then

NhapDL;

Writeln;

Trang 14

Writeln('* DU LIEU VAO: '); HienthiDL;

Readln;

Writeln('* LAP BANG');

Lap_bang;

Writeln;

Writeln('* KET QUA: ');

Tong_hop;

Write('Tong diem: ',diem[m,n]); Readln;

END

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

🧩 Sản phẩm bạn có thể quan tâm

w