Nêu bài toán Định nghĩa xâu trong: S là xâu trong của T nếu S nhận được bằng cách xoá đi một số ký tự nào đó của T.. Ví dụ: ‘ABC’ là xâu trong của ‘GAHEBOOC’ bằng cách xóa đi các ký tự G
Trang 1Bài 3: bài toán tìm xâu trong chung cực đại của 2 xâu cho trước
3.1 Nêu bài toán
Định nghĩa xâu trong: S là xâu trong của T nếu S nhận được bằng cách xoá đi một số ký tự nào đó của T
Ví dụ: ‘ABC’ là xâu trong của ‘GAHEBOOC’ bằng cách xóa đi các ký tự GHEOO của xâu
‘GAHEBOOC’
Bài toán: Cho 2 xâu T1, T2 Tìm một xâu S là xâu trong chung của T1 và T2 có độ dài cực đại
Ví dụ: T1=‘ABCDAE’ và T2=‘XYACADK’ có xâu ‘ACD’ là xâu trong chung với độ dài cực đại
Ta có thông tin vào và thông tin ra của bài toán là:
+ Input: Hai xâu T1,T2
+ Output: Độ dài cực đại của xâu của xâu con chung và xâu con chung S.
3.2 Phương pháp thực hiện, sử dụng phương pháp quy hoạch động với 4 bước là:
Bước 1: Phân tích bài toán
Giả sử ta có:
Xâu T1 = “a1a2…am”, chiều dài: m
Xâu T2 = “b1b2…bn”, chiều dài: n
Gọi L(r,s) là bài toán xâu con chung cực đại, với
r ∈ N: Độ dài dãy a1a2…am( r ≤ m )
s ∈ N: Độ dài dãy b1b2…bn (s ≤ n) (Bài toán ban đầu là L(m, n))
Các giá trị cần tìm:
L[r,s]: độ dài cực đại của xâu con chung của bài toán L(r, s).
S: xâu con chung của bài toán L(r,s)
Trang 2Bước 2: Giải pháp đệ quy
- T/h 1:Khi (r=0) hoặc (s=0)
L(r,s)=0 {Một trong hai xâu đã cho là rỗng thì độ dài xâu chung cực đại bằng 0}
- T/h 2: Khi (r>0) và (s>0) và (ar<> bs)
L(r,s) = Max(L(r-1,s), L(r,s-1))
- T/h 3: Khi (r>0) và (s>0) và (ar=bs)
L(r,s)= 1 + L(r-1,s-1)
Bước 3: Lập bảng
Nhận xét:
- Ta nhận thấy nếu T1r=T2s, lúc xâu con chung cực đại S của T1 và T2 có thể tính bằng xâu con chung cực đại S’ của Tr-1 và Ts-1, đồng thời nối ai vào cuối, tức S = S’+ ar
- Nếu T1<>T2s, lúc này cho S1 là độ dài xâu chung cực đại xâu của Tr-1 và Ts, và S2 là độ dài xâu chung cực đại của Tr và Ts-1 S sẽ là giá trị lớn nhất trong 2 giá trị S1 và S2
L[r,s] =
1 + L[r -1, s – 1] nếu T1i = T2j Max(L[r -1, s], L[r, s -1]) nếu T1r <> T2s
Độ phức tạp tính toán là: O(m*n)
Procedure Lapbang;
var r,s:integer;
begin
n:=length(T1); m:=length(T2);
for r:=0 to m do
for s:=0 to n do
if (r=0)or(s=0) then
Begin l[r,s] := 0; u=‘’; end else if T1[r]=T2[S] then
Trang 3l[r,s] := l[r-1,s-1]+1; u:=T1[r];
End
else
l[r,s]:= Max(l[r-1,s],l[r,s-1]);
End;
Bước 4: Tổng hợp kết quả
Để tìm xâu kết quả S: Ta đi ngược từ ô L[m,n] hướng về ô L[0, 0]
- Nếu ar= bs thì đặt ai hoặc bj vào bên trái dãy S (ở đầu xâu) và về ô L[r-1,s-1]
- Nếu ar <> bs thì
+ lùi về L[r - 1, s] trong trường hợp L[r - 1, s] > L[r, s - 1]
+ ngược lại, lùi về L[r, s – 1] trong trường hợp L[r - 1, s] ≤ L[r,s – 1]
Procedure THKQ;
Begin
u:=’’; r:= n; s := m;
While (r > 0) And (s >0) Do
Begin
If T1[r] = T2[s] Then
Begin
u := u+T1[r]; dec(r); dec(s);
End Else If L[r - 1, s] > L[r, s - 1] then dec(r)
Else dec(s);
End;
Writeln(f,‘Do dai xau chung cuc dai là: ’, length(u));
Writeln(f,‘Xau chung cuc dai là:’, u);
Close(f);
End;
Độ phức tạp: O(max(n,m))
CHƯƠNG TRÌNH CHÍNH
Trang 4CLRSCR;
Nhapdl;
Lapbang;
Tonghopketqua;
END.
CHƯƠNG TRÌNH MÔ PHỎNG TÌM XÂU CON CHUNG CỰC ĐẠI BẰNG NNLT PASCAL
Uses crt;
Const f1='XAU.INP'; f2='KETQUA.OUT';
Var n,m,r,s:integer;
T1,T2:String;
x:Array[1 10] of string;
l:Array[1 10,1 10] of integer;
u:String;
f:text;
Procedure NhapDL;
Begin
assign(f,f1); reset(f);
readln(f,T1); readln(f,T2);
close(f);
assign(f,f2); rewrite(f);
End;
Function max(x,y:integer):integer;
Begin
If x>y Then max:=x Else max:=y;
End;
Procedure lapbang;
Trang 5m:=length(T1); n:=length(T2);
{FillChar(L, SizeOf(L), 0);}
For r:=1 To m Do
For s:=1 To n Do
If T1[r] = T2[s] Then
L[r,s]:= 1 + L[r-1,s-1]
Else
L[r,s]:= max (L[r,s-1] , L[r-1,s]); End;
Procedure tonghopketqua;
Begin
r:=m; s:=n; u:='';
While (r>0) and (s>0) Do
Begin
If T1[r]=T2[s] Then
Begin
Insert(T1[r], u, 1);
Dec(r);
Dec(s);
End
Else
Begin
If L[r, s]= L[r-1, s] Then Dec(r) Else Dec(s);
End;
End;
Writeln(f,'Do dai xau chung cuc dai la: ', length(u));
Trang 6Writeln(f,'Xau chung cuc dai la: ',u);
Writeln(f,'Bang phuong an toi uu.');
For r:=1 To m Do
Begin
For s:=1 To n Do
write(f,l[r,s]:4);
writeln(f);
End;
Close(f);
End;
BEGIN
nhapDL;
lapbang;
tonghopketqua;
END.
Giả sửa file XAU.INP khi chạy chương trình trên ta được file KETQUA.OUT như sau:
ABCDAE
XYACADK
Do dai xau chung cuc dai la: 3 Xau chung cuc dai la: ACD Bang phuong an toi uu
0 0 1 1 1 1 1
0 0 1 1 1 1 1
0 0 1 2 2 2 2
0 0 1 2 2 3 3
0 0 1 2 3 3 3
0 0 1 2 3 3 3
Trang 7Bài 4: bài toán Du lịch
4.1 Nê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 (hoặc không đi qua) các 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é của xe đi từ thành phố i đến thành phố j là c[i,j] (với 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
Từ bài toán đã nêu, ta có thông tin đầu vào và đầu ra của bài toán như sau:
+ Input: + n là thành phố cần đến
+ C[i, j] là ma trận về vé xe để đi từ thành phố i đến thành phố j (i, j =0 n)
+ Output: Đường đi đến thành phố n sao cho chi phí nhỏ nhất
4.2 Phương pháp thực hiện, sử dụng phương pháp quy hoạch động theo 4 bước sau:
Bước 1 Phân tích bài toán
- Gọi ρ(s) là bài toán du lịch, với: 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:
o l[s]: chi phí nhỏ nhất để đi từ thành phố 0 → s của bài toán ρ(s)
o u[s]: đỉnh kế cuối trên đường đi từ thành phố 0 → s của bài toán ρ(s)
Bước 2 Giải pháp đệ quy
- Khi s = 0 thì
o l[s] = 0
Trang 8o u[s] = -1 ( vì không có đỉnh kế cuối)
- Khi s > 0 :
o l[s] = min (l[k] + c[k,s]) (0≤k<s)
= l[k’] + c[k’,s]
(với k’ là chi phi đi từ đỉnh 0 đến đỉnh kế cuối nhỏ nhất)
o 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;
Độ phức tạp tính toán: O(n 2 )
Bước 4 Tổng hợp kết quả
Procedure Tonghop;
Var i, s : byte;
Begin
s := n; {Xuất phát từ thành phố s cuối cùng, ta đi ngược trở lại để tìm các điểm đã đi qua} i:=0; {mảng X[i] dùng để lưu dấu vết các địa điểm thành phố đã đi qua}
Trang 9while ((s>=0) do {Max la so lon nhat neu khong co duong di qua 1 cap dinh}
Begin
i := i+1;
X[i] := s;
s := u[s];
End;
Writeln(‘Chi phi nho nhat cua duong di la: ’, L[n]);
Write('Duong di voi chi phi nho nhat: ');
for s := i downto 1 do write(x[s],’ ‘);
End;
End;
• Độ phức tạp tính toán: O(n)
CHƯƠNG TRÌNH MÔ PHỎNG BÀI TOÁN DU LỊCH BẰNG NNLT PASCAL
Trang 10Bài 5: Bài toán sinh viên ôn thi
5.1 Nêu bài toán:
Một sinh viên cần ôn thi n môn trong m ngày Theo kinh nghiệm của anh ta, nếu ôn môn i trong j 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,j+1])
Tìm bộ x[i] (số ngày ôn môn i, với i =1 n) sao cho Σx[i] = m và sinh viên đạt tổng điểm lớn nhất (hay:
Σa[x[i], i] → max)
Từ nội dung bài toán, ta thấy thông tin vào và ra của bài toán như sau:
+ Input: n: số môn thi
m: số ngày ôn thi a[i,j]: ma trận thể hiện điểm môn i nếu ôn trong j ngày (i: 1 n , j: 1 m)
+ Output: x[i] là số ngày ôn thi của môn i (i = 1 n) sao cho Σa[x[i], i] → max)
n-1
n
Số ngày ôn thi (x[i])
5.2 Phương pháp thực hiện, sử dụng phương pháp quy hoạch động theo 4 bước sau:
B1: Phân tích bài toán
Gọi P(r,s) là bài toán sinh viên ôn thi s môn trong r ngày
=>Bài toán ban đầu: P(m,n)
Các giá trị cần tìm:
l[r,s]: số điểm cực đại
Trang 11u[r,s]: số ngày tối ưu để ôn môn s
B2: Phương pháp đệ quy
• s>1
l[r,s] = Max(l[r-k,s-1] + a[k,s])
0=<k<=r
u[r,s]=k
• s=1
l[r,s] = a[r,s]
u[r,s] = r
B3: Lập bảng
Procedure LapBang
Begin
For s:=1 to n do
Begin
l[0,s]=0;
u[0,s]=0;
End;
For s:=1 to n do
For r:=1 to m do
Tinh;
End;
Procedure Tinh
Begin
If s=1 then
Begin
l[r,s]:= a[r,s]
u[r,s]:= r;
End
Else
Begin
Trang 12k1:=0; Max:=l[r,s-1];
For k:=1 to r do
Begin
tam:=a[k,s] + l[r-k,s-1];
If tam>Max then
Begin
Max:=tam; k1:=k; End;
End;
l[r,s]:= Max;
u[r,s]: = k1;
End;
End;
Procedure TongHop
Begin
S:=n; r:=m;
For s:=n downto 1 to
Begin
x[s]:= u[r,s];
r:=r – x[s];
End;
End;
Trang 13Ví dụ:
Số điểm cao nhất: 10 Môn 1: 3 ngày
Môn 2: 3 ngày Môn 3: 1 ngày
3 7
1 2 2
2 3 3
3 5 4
4 6 5
5 7 6
6 8 7
7 9 8
Trang 14CHƯƠNG TRÌNH MÔ PHỎNG BÀI TOÁN SINH VIÊN ÔN THI BẰNG NNLT PASCAL
Uses crt;
Const fname='onthi.in';
Var n,p,m:integer;
x:array[1 10] of integer;
a,u,l:array[0 10,0 10] of integer;
f:Text;
Procedure NhapDL;
Var i,j:integer;
Begin
Assign(f,fname);
reset(f);
Readln(f,n,m); {n mon, m ngay}
for i:=1 to m do
Begin
For j:=1 to n do
Read(f,a[i,j]);
End;
Close(f);
End;
Procedure LapBang;
Var r,s,k1,Max,tam,k:integer;
Begin
For s:=1 to n do
Begin
l[0,s]:=0;
u[0,s]:=0;
Trang 15End;
For s:=1 to n do
For r:=1 to m do
If s=1 then
Begin
u[r,1]:= r;
l[r,1]:= a[r,1];
End
Else
Begin
k1:=0;
Max:=l[r,s-1];
For k:=1 to r do
Begin
tam:= a[k,s] + l[r-k,s-1];
If tam>Max then
Begin
Max:=tam;
k1:=k;
End;
End;
l[r,s]:=Max;
u[r,s]:=k1;
End;
End;
Procedure TongHop;
Trang 16Var s,r,i:integer;
Begin
s:=n;
r:=m;
For s:=n downto 1 do
Begin
x[s]:=u[r,s];
r:=r - x[s];
End;
Writeln('Diem toi da:',l[m,n]); For i:=1 to n do
Writeln('Mon ',i,':',x[i],' ngay'); End;
Procedure XuatMang;
Var i,j:integer;
Begin
For i:=1 to m do
Begin
For j:=1 to n do
Write(a[i,j],' ');
Writeln;
End;
End;
BEGIN
Clrscr;
NhapDL;
Trang 17{ Xuatmang;} LapBang; TongHop; Readln; END.