Tổng ônMôn : thiết kế thuật toánI / Dynamic programing a Gán nhãn Dijsktra Tìm đờng đi ngắn nhất trên đồ thị có trọng số không âm từ đỉnh u nguồn tới mọi đỉnh d đích.. + Tại mỗi bớc t
Trang 1Tổng ônMôn : thiết kế thuật toán
I / Dynamic programing
a) Gán nhãn (Dijsktra) Tìm đờng đi ngắn nhất trên đồ thị có trọng số không âm từ đỉnh u (nguồn ) tới mọi đỉnh d ( đích ) Trọng số C[i,j] là trọng số từ đỉnh i tới đỉnh j
Trớc hết ta gọi nhãn của đỉnh i ( i : 1<= i <= N ) là cặp số ( b,v ) với ý nghĩa : b là
đỉnh kề ngay trớc i của đờng đi ngắn nhất từ u tới i , v là giá trị đờng đi ngắn nhất từ u tới
i Ký hiệu i ( b,v )
+ khởi trị nhãn :
* nhãn mọi đỉnh i là : i ( 0, Max ) i : 1<= i <= N
* nhãn đỉnh xuất phát là : u ( u ,0 )
* Ghi nhận đỉnh x = u và kết nạp x vào tập đỉnh đã xét : ex[x] = 1
+ Trong khi x<>d ( đích ) và ( x<>0 ) thực hiện vòng lặp :
begin
* sửa nhãn các đỉnh i ( b i ,v i ) cha kết nạp và có đờng đi từ x tới i theonguyên tắc : gỉa sử nhãn x là x (bx , v x ) , nếu bx+ C[x,i] < bi thì đỉnh i cónhãn mới là i ( x, bx+ C[x,i] )
* Chọn đỉnh i0 có nhãn nhỏ nhất trong các đỉnh cha kết nạp vào tập đỉnh đãxét , nếu tìm đợc thì kết nạp i0 vào tập đỉnh đã xét , gán x = i0 Nếu khôngchọn đợc thì x = 0
+ ghi lu i vào mảng kết quả
+ i nhận giá trị nhãn thứ nhất của i end;
uses crt;const max = 100; fi = 'dijsktra.001';type tc = array[1 max,1 max] of integer;{ cost } tb = array[1 max] of shortint; { befor } tv = array[1 max] of integer; { value } tr =
array[1 max] of char; { result }
tex = array[1 max] of 0 1; { examined : da xem xet }
Trang 2function chon : byte;
var i,li : byte;
Trang 3b) Bài toán 0/1 _knapsack :
Cho n đồ vật , đồ vật thứ i có trọng lợng là wi , giá trị là vi Ngời ta xếp các đồ vậtvào 1 chiếc va ly có sức chứa tối đa là limw Hãy chọn những đồ vật nào xếp vào va ly đểgiá trị va ly là lớn nhất
Đây là bài toán tìm véc tơ x = (x1 , x2 , , xn ) với xi chỉ nhận giá trị 0,1 , sao cho
Trang 4for i:=1 to n do read(f,w[i]);
for i:=1 to n do read(f,v[i]);
for i:=1 to n do write(w[i]:4);writeln;
for i:=1 to n do write(v[i]:4);writeln;
end;
procedure taobang;
var i,j : integer;
function max2(x,y : integer) : integer;
Trang 5Writeln(g,'tong gia tri va ly : ',f[n,limw]);
Writeln(g,'tong trong luong : ',tong);
writeln('da chay xong chuong trinh ');
close(g);
readln;
END
II / Đệ quy
Bài tập 2 : Mã đi tuần :
Cách 1 : Đệ quy tìm mọi nghiệm , chỉ chạy đợc với n khoảng 6 hoặc 7
uses crt;const max = 10; dy : array[1 8] of -2 2 = (-1, 1, 2, 2, 1, -1,-2,-2);
Trang 6for j:=-1 to n+2 do a[i,j] := -1; for i:=1 to m do
end;
end;
procedure vet(i,x,y : integer);
var j,u,v : integer;
Trang 7III / Tham lam :
Bài mã đi tuần (Cách 2) Tham lam , tìm 1 nghiệm chạy đợc với n khoảng 30 hoặc 40
{$A+,B-,D+,E+,F-,G-,I+,L+,N-,O-,P-,Q-,R+,S+,T-,V+,X+}{$M 56384,0,655360}Uses crt;Const Max = 50; dx : Array[1 8] of integer=(-2,-2,-1,1, 2, 2,1,-1); dy : Array[1 8] of integer=( -1,1, 2,2,1,-1,-2,-2);
Var N,x,y : Integer;
Function Bac(x,y:integer) : Integer;
Var i,dem : Integer;
Begin
dem:=0;
Trang 9function bac(x,y : integer) : integer;
var i,j,dem : integer;
procedure chon(x,y : integer;var u,v:integer);
var i,b,lb,lx,ly : integer;
Trang 10+ Tại mỗi bớc tìm kiếm có 1 tập hữu hạn các khả năng Pset(i) = Ai | Bi
Mỗi tập khả năng của bớc i gồm 2 tập con không giao nhau Ai và Bi Trong đó Ai là tập cákhả năng đã duyệt , Bi cha duyệt Nếu Bi = (mọi khả năng của bớc i đã duyệt hết ) mà cha đạt kết quả thì lùi một bớc trở về bớc trớc Ngợc lại khi Bi khác rỗng thì ta chọn một khả năng của Bi , cho đi tiếp Thuật toán kết thúc khi gặp kết quả
Ngợc lại , sau khi thăm hết mọi khả năng của mọi bớc mà không đạt két quả ta cũng dừng thuật toán
Các bài toán loại này kết quả thờng chứa 2 điều kiện P và Q Khi tìm kiếm ta ờng tạm bỏ qua 1 điều kiện , thí dụ nh bỏ điều kiện P , tại mỗi bớc tìm kiếm ta chỉ cần khảo sát các khả năng thoả mãn điều kiện Q
th-Sơ đồ giải tìm 1 nghiệm :
Khởi trị mảng chứa kết quả V thoả mãn điều kiện P
Repeat
If gặp Đích then begin Hiện nghiệm ; exit ; end;
If Thất bại then begin Thông báo vô nghiệm ; exit ; end;
If Có đờng then Tiến
Else LuiUntil false;
Sơ đồ giải tìm mọi nghiệm :
Khởi trị mảng chứa kết quả V thoả mãn điều kiện P
Repeat
If gặp Đích then begin Hiện nghiệm ; Lui ; end;
If Thất bại then begin Thông báo vô nghiệm ; exit ; end;
If Có đờng then Tiến
Else LuiUntil false;
Trang 11Bài mã đi tuần (Cách 3 ) Duyệt quay lui ( backtracking ) tìm mọi nghiệm , chỉ chạy đợc
function tien_duoc(var x,y,sb : integer) : integer;
var u,v : integer;
begin
tien_duoc := 9;
for k:=1 to 8 do
Trang 12if sn=0 then write(f,'vo nghiem ')
else write(f,'tong so nghiem la : ',sn);
Bµi N_hËu : H·y xÕp N qu©n hËu trªn bµn cê N*N sao cho chóng kh«ng khèng chÕ nhau
ThuËt to¸n Backtracking
Trang 13uses crt;const max = 20;
if i<1 then break;
if tien(i) then inc(i)
else
begin
v[i] := 0;
dec(i);
Trang 14Bài 6 : Tìm từ chân chính ( chỉ gồm các kí tự thuộc tập A=[‘1’ ’9’] , không có 2 xâu con
liền nhau bằng nhau ) sao cho độ dài của từ bằng số nguyên N ( N <= 40000 ) và ký tự C thuộc tập A chỉ xuất hiện không quá K lần
for j:= k downto k-i+1 do
if w[j]<>w[j-i] then exit;
for i:=1 to k div 2 do { i : do dai 2 xau con lien nhau }
if equal(i,k) then exit;
pure := true;
end;
function k_tu_c(k : longint) : boolean;
var i,p : longint;
begin
p := 0;
k_tu_c := false;
for i:=1 to k do
Trang 15begin
if w[i]=kituc then inc(p);
if p>sok then exit;
if k>n {dich} then result;
if k<1 {thatbai} then break;
if coduong and (k<=n) then inc(k) {tien}
Trang 16if k<1 (*that bai*) then
begin writeln(f,'vo nghiem ');close(f);exit;end;
if coduong and (k<=n) then inc(k) (*tien*)
write('ki tu lap la : ');readln(kituc);
write('so lan lap la : ');readln(sok);
init;
PW;
END
V Thuật toán khác :
Bài 4 : Cho N số nguyên dơng thuộc tập P , Hãy tìm tập con S của P sao cho với mọi số x
trong P đếu có thể biểu diễn dới dạng tích chỉ gồm các số thuôc tập con S
Thuật toán tìm tập cơ sở ( dùng dữ liệu kiểu queue )
program sinh;uses crt;const max = 10000; fi = 'input.inp';
fo = 'output.txt';type mang = array[1 max] of integer;
mang2 = array[1 max] of byte;
var a,q : mang;
Trang 17procedure qs(dau,cuoi : integer);
var i,j,g,coc :integer;
begin
i:=dau; j:=cuoi;
g:=a[(dau+cuoi) div 2];
repeat
while a[i]<g do inc(i);
while a[j]>g do dec(j);
if i<cuoi then qs(i,cuoi);
if j>dau then qs(dau,j);
end;
function duoc(k : integer) : boolean;
var dau,cuoi : integer;
Trang 18Bài 5 : Cho n số nguyên dơng đôi một khác nhau là tập S Hãy chọn từ S một tập con P
có ít phần tử nhất mà với mọi (x,y) | x S , y P thì UCLN (x,y) <> 1
Thuật toán tìm tập ổn định ngoài
uses crt;const max = 30; fi = 'ondinh2.inp'; fo = 'ondinh2.out';type mang = array[0 max] of integer; mang2 =
array[0 max,0 max] of 0 1;var a,b : mang;
Trang 20if khong_thuoc then
if not noi then
begin od_ngoai := False; exit; end;
Trang 21Bài 7 : Bài toán sắp ba lô : Cho n đồ vật , đồ vật thứ i có trọng lợng là wi , giá trị là vi
.Ngời ta xếp các đồ vật vào 1 chiếc va ly có sức chứa tối đa là limw Hãy chọn những đồ vật nào xếp vào va ly để giá trị va ly là lớn nhất
Đây là bài toán tìm véc tơ x = (x1 , x2 , , xn ) với xi chỉ nhận giá trị 0,1 , sao cho
for i:=1 to n do read(f,w[i]);
for i:=1 to n do read(f,v[i]);
for i:=1 to n do write(w[i]:4);writeln;
for i:=1 to n do write(v[i]:4);writeln;
end;
procedure taobang;
var i,j : integer;
function max2(x,y : integer) : integer;
Trang 22Writeln(g,'tong gia tri va ly : ',f[n,limw]);
Writeln(g,'tong trong luong : ',tong);
writeln('da chay xong chuong trinh ');
close(g);
readln;
END