Bước 1. Phân tích bài toán
- Gọi P(r) là bài toán du lịch với r là đỉnh cần đến, điểm xuất phát là 0. Bài toán ban đầu P(n)
- Cách giá trị cần tìm:
l[r]: Chi phí nhỏ nhất để đi từ đỉnh 0 đến đỉnh r.
u[r]: Đỉnh kế cuối trong đường đi từ đỉnh 0 đến đỉnh r.
Bước 2. Giải pháp đệ quy
- Trường hợp chung: khi r > 0
l[r] = min(l[k] + c[k,r]) (k= 0 -> r-1)
= l[k1] + c[k1,r]
u[r] = k1
- Trường hợp đệ quy: khi r=0 l[r] = 0;
u[r]= 0;
Trong đó:
k1 : đỉnh mà tại đó có chi phí nhỏ nhất để đi từ 0 đến k c[k1,r]: chi phí nhỏ nhất để đi từ k1 đến r.
Bước 3. Lập bảng
- Hướng tính:
Procedure Lapbang;
Begin
for r:= 0 to n do
if (r = 0) then Tính l[0] và u[0]
else Tính l[r] và u[r]
End;
Độ phức tạp tính toán: O(n2) - Lập bảng:
Procedure LapBang;
var r, v, v1, min: integer;
begin
for r:=0 to n do begin
if r = 0 then begin
l[r]:=0;
u[r]:=0;
end else
begin
v1:= 0;
min:= c[0,r];
for v:=0 to r-1 do
begin
if min > l[v]+C[v,r] then begin
min:= l[v]+C[v,r];
v1:= v;
end;
end;
l[r]:= min;
u[r]:= v1;
end;
end;
end;
Độ phức tạp tính toán: O(n2) Bước 4. Tổng hợp kết quả Procedure TongHop;
var r,i: integer;
begin r:= n;
writeln('Chi phi toi thieu de di la: ', l[n]);
x[r]:=n;
while r<>0 do begin
x[r-1]:= u[r];
r:= u[r];
end;
writeln('Lo trinh duong di ngan nhat: ');
for i:= 1 to n do begin
if x[i]=n then write(x[i]) else write(x[i],'--->');
end;
end;
Độ phức tạp tính toán: O(n)
CODE BÀI TOÁN DU LỊCH Program BT_DuLich;
const nMax = 100;
input = 'DuLich.txt';
var u,l: array [0..nMax] of integer;
C: array [0..nMax,1..nMax] of integer;
x: array [1..nMax] of integer;
n: integer;
Procedure Doc_DL;
var f: text;
i,j,t: integer;
begin
assign(f,input);
reset(f);
readln(f,n);
for i:=0 to n do for j:=0 to n do
begin
read(f,t);
if t>0 then c[i,j]:=t else c[i,j]:= MaxInt;
end;
close(f);
end;
Procedure LapBang;
var r, v, v1, min: integer;
begin
for r:=0 to n do begin
if r = 0 then begin
l[r]:=0;
u[r]:=0;
end else
begin
v1:= 0;
min:= c[0,r];
for v:=0 to r-1 do begin
if min > l[v]+C[v,r] then begin
min:= l[v]+C[v,r];
v1:= v;
end;
end;
l[r]:= min;
u[r]:= v1;
end;
end;
end;
Procedure TongHop;
var r,i: integer;
begin r:= n;
writeln('Chi phi toi thieu de di la: ', l[n]);
x[r]:=n;
while r<>0 do begin
x[r-1]:= u[r];
r:= u[r];
end;
writeln('Lo trinh duong di ngan nhat: ');
for i:= 1 to n do begin
if x[i]=n then write(x[i]) else write(x[i],'--->');
end;
end;
begin
Doc_DL;
LapBang;
TongHop;
readln;
end.
Kết quả chạy thử Dữ liệu đầu vào:
4
0 1 2 4 -1 1 0 -1 2 5 2 -1 0 3 -1 4 2 3 0 2 -1 5 -1 2 0
Dữ liệu đầu vào:
3 0 6 2 -1 6 0 1 3 2 1 0 5 -1 3 5 0 Kết quả:
Chi phi toi thieu de di la: 5 Lo trinh duong di ngan nhat:
0--->1--->3--->4
Kết quả:
Chi phi toi thieu de di la: 7 Lo trinh duong di ngan nhat:
0--->2--->3
Bài tập 13 : Bài toán sinh viên ôn thi 1. 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à c[i,j]. Giả sử cho biết các c[i,j] (với
c[i,j]<=c[i+1,j]).
Tìm bộ x[j] (số ngày ôn thi môn j, j=1..n) sao cho Σx[j]=m và sinh viên đạt tổng điểm lớn nhất (Σc[x[j],j] đạt max)
Input:
m ∈N: số ngày ôn thi
n ∈N* : số môn ôn thi.
c[i,j] ∈R: điểm đạt được khi ôn thi môn j trong i ngày.
Output:
x[j]: số ngày ôn thi môn j (j=1..n) sao choΣx[j]=n và Σc[x[j],j] đạt max
Môn thi thứ i 1 2 … n-1 n
Số ngày ôn thi (x[i]) ? ? … ? ?
2. Phương pháp thực hiện theo 4 bước sau:
Bước 1. Phân tích bài toán
Gọi P(r,s) là bài toán ôn thi với r : là số ngày ôn thi
s : là số môn ôn thi
=> Bài toán ban đầu: P(m,n) Tìm:
l[r,s]: tổng điểm lớn nhất Σc[x[j],j]
u[r,s]: số ngày ôn thi môn s (tức là x[s]) Bước 2. Giải pháp đệ quy
- Trường hợp chung: khi s > 1
l[r,s] = max (c[k,s]+l[r-k,s-1]) với (0≤k≤ r)
= c[k1,s]+l[r-k1,s-1]
u[r,s]=k1
- Trường hợp đệ quy: khi s=1 u[r,s]=u[r,1]=r
l[r,s]=l[r,1]=c[r,1]
Bước 3. Lập bảng
- Hướng tính:
- Lập bảng:
procedure Lap_Bang;
var r,s,k,k1,tam,max: integer;
begin
for s:=1 to n do
for r:= 0 to m do if s=1 then
begin
l[r,s]:= c[r,1];
u[r,s]:= r;
end else
begin
k1:= 0;
max:= l[r,s-1];
for k:=0 to r do begin
tam:= c[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;
Độ phức tạp tính toán: O(n2) Bước 4. Tổng hợp kết quả
procedure Tong_hop_KQ;
var i,r,s: integer;
begin
r:=m;
for s:=n downto 1 do begin
x[s]:= u[r,s];
r:= r- x[s];
end;
writeln('So diem toi da co the duoc la: ',l[m,n]);
writeln('So ngay can on cho cac mon la: ');
for i:= 1 to n do writeln ('Mon ',i,':',x[i]:4);
end;
Độ phức tạp tính toán: O(n)
CODE BÀI TOÁN SINH VIÊN ÔN THI program SV_OnThi;
const nMax = 100;
input = 'SV_OnThi.txt';
var c,l,u: array [0..nMax,1..nMax] of integer;
x: array [0..nMax] of integer;
m, n: integer;
procedure Doc_DL;
var f: text;
i,j: integer;
begin
assign(f,input);
reset(f);
readln(f,m,n);
for i:=0 to m do begin
j:=1;
while not eoln(f) do begin
read(f, c[i,j]);
j:=j+1;
end;
readln(f);
end;
close(f);
end;
procedure Lap_Bang;
var r,s,k,k1,tam,max: integer;
begin
for s:=1 to n do
for r:= 0 to m do if s=1 then
begin
l[r,s]:= c[r,1];
u[r,s]:= r;
end else
begin
k1:= 0;
max:= l[r,s-1];
for k:=0 to r do begin
tam:= c[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;