Phương pháp thực hiện theo 4 bước sau

Một phần của tài liệu Bài tập phân tích và thiết kế thuật toán (Trang 33 - 43)

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;

Một phần của tài liệu Bài tập phân tích và thiết kế thuật toán (Trang 33 - 43)

Tải bản đầy đủ (PDF)

(43 trang)