bài giảng các chuyên đề (tài liệu nói về các chuyên đề thuật toán, đồ thị, cây của thầy lê minh hoàng khối chuyên tin đại học sư phạm hà nội - Pdf 23


class="bi x1 y1 w1 h1"
Bài toán lit kê
Lê Minh Hoàng
{ 1z
MC LC
§
0. GI
I THIU
2
§
1. NH
C LI MT S KIN THC I S T HP
3
I. CH
NH HP LP
3
II. CH
NH HP KHÔNG LP
3
III. HOÁN V

3
IV. T
 HP
3
§
2. PH
NG PHÁP SINH (GENERATE)
5
I. SINH CÁC DÃY NH

22
I. BÀI TOÁN T
I U
22
II. S
 BÙNG N T HP
22
III. MÔ HÌNH K
 THUT NHÁNH CN
22
IV. BÀI TOÁN NG
I DU LCH
23
V. DÃY ABC 25
Bài toán lit kê
Lê Minh Hoàng
{ 2z
§
0. GII THIU
Trong thc t, có mt s bài toán yêu cu ch rõ: trong mt tp các đi tng cho trc có bao
nhiêu đi tng tho mãn nhng điu kin nht đnh. Bài toán đó gi là bài toán đm cu hình t
hp.
Trong lp các bài toán đm, có nhng bài toán còn yêu cu ch rõ nhng cu hình tìm đc tho
mãn điu kin đã cho là nhng cu hình nào. Bài toán yêu cu đa ra danh sách các cu hình có th
có gi là bài toán lit kê t hp.
 gii bài toán lit kê, cn phi xác đnh đc mt thut toán đ có th theo đó ln lt xây dng
đc tt c các cu hình đang quan tâm. Có nhiu phng pháp lit kê, nhng chúng cn phi đáp
ng đc hai yêu cu di đây:
• Không đc lp li mt cu hình
• Không đc b sót mt cu hình

chnh hp lp chp k ca S. Nh ví d trên (E, C, E) là mt chnh hp lp chp 3 ca S. D dàng
chng minh đc kt qu sau bng quy np hoc bng phng pháp đánh giá kh nng la chn:
S chnh hp lp chp k ca tp gm n phn t:
k
k
n
nA =
II. CHNH HP KHÔNG LP
Khi f là đn ánh có ngha là vi ∀i, j ∈ X ta có f(i) = f(j) ⇔ i = j. Nói mt cách d hiu, khi dãy giá
tr f(1), f(2), , f(k) gm các phn t thuc S khác nhau đôi mt thì f đc gi là mt chnh hp
không lp chp k ca S. Ví d mt chnh hp không lp (C, A, E):
i 123
f(i) C A E
S chnh hp không lp chp k ca tp gm n phn t:
)!kn(
!n
)1kn) (2n)(1n(nA
k
n

=+−−−=
III. HOÁN V
Khi k = n. Mt chnh hp không lp chp n ca S đc gi là mt hoán v các phn t ca S.
Ví d: mt hoán v: (A, D, C, E, B, F) ca S = {A, B, C, D, E, F}
i123456
f(i) A D C E B F
 ý rng khi k = n thì s phn t ca tp X = {1, 2, , n} đúng bng s phn t ca S. Do tính cht
đôi mt khác nhau nên dãy f(1), f(2), , f(n) s lit kê đc ht các phn t trong S. Nh vy f là
toàn ánh. Mt khác do gi thit f là chnh hp không lp nên f là đn ánh. Ta có tng ng 1-1 gia
các phn t ca X và S, do đó f là song ánh. Vy nên ta có th đnh ngha mt hoán v ca S là mt

1
n
0
n
2)11(C CC
=+=+++
Bài toán lit kê
Lê Minh Hoàng
{ 5z
§
2. PHNG PHÁP SINH (GENERATE)
Phng pháp sinh có th áp dng đ gii bài toán lit kê t hp đt ra nu nh hai điu kin sau
tho mãn:
1. Có th xác đnh đc mt th t trên tp các cu hình t hp cn lit kê. T đó có th xác
đnh đc cu hình đu tiên và cu hình cui cùng trong th t đã xác đnh
2. Xây dng đc thut toán t cu hình cha phi cu hình cui, sinh ra đc cu hình k
tip nó.
Phng pháp sinh có th mô t nh sau:
<Xây dng cu hình đu tiên>;
repeat
<a ra cu hình đang có>;
<T cu hình đang có sinh ra cu hình k tip nu còn>;
until <ht cu hình>;
Th t t đin
Trên các kiu d liu đn gin chun, ngi ta thng nói ti khái nim th t. Ví d trên kiu s
thì có quan h: 1 < 2; 2 < 3; 3 < 10; , trên kiu ký t Char thì cng có quan h 'A' < 'B'; 'C' < 'c'
Xét quan h th t toàn phn "nh hn hoc bng" ký hiu "≤" trên mt tp hp S, là quan h hai
ngôi tho mãn bn tính cht:
Vi ∀a, b, c ∈ S
• Tính ph bin: Hoc là a ≤ b, hoc b ≤ a;

• Hoc a
i
= b
i
vi ∀i: 1 ≤ i ≤ n.
• Hoc tn ti mt s nguyên dng k: 1 ≤ k < n đ:
a
1
= b
1
a
2
= b
2

a
k-1
= b
k-1
a
k
= b
k
a
k+1
< b
k+1
Trong trng hp này, ta có th vit a < b.
Th t đó gi là th t t đin trên các dãy đ dài n.
Khi đ dài hai dãy a và b không bng nhau, ngi ta cng xác đnh đc th t t đin. Bng cách

-1.
Ví d: Khi n = 3, các dãy nh phân đ dài 3 đc lit kê nh sau:
p(x)01234567
x 000 001 010 011 100 101 110 111
Nh vy dãy đu tiên s là 00 0 và dãy cui cùng s là 11 1. Nhn xét rng nu dãy x = (x
1
, x
2
, ,
x
n
) là dãy đang có và không phi dãy cui cùng thì dãy k tip s nhn đc bng cách cng thêm 1
( theo c s 2 có nh) vào dãy hin ti.
Ví d khi n = 8:
Dãy đang có:
10010000
Dãy đang có:
10010111
cng thêm 1:
+ 1
cng thêm 1:
+ 1
 
Dãy mi:
10010001
Dãy mi:
10011000
Nh vy k thut sinh cu hình k tip t cu hình hin ti có th mô t nh sau: Xét t cui
dãy v đu (xét t hàng đn v lên), gp s 0 đu tiên thì thay nó bng s 1 và đt tt c các phn
t phía sau v trí đó bng 0.

{ 7z
var
x: array[1 max] of Integer;
n, i: Integer;
begin
{nh ngha li thit b nhp/xut chun}
Assign(Input, 'BSTR.INP'); Reset(Input);
Assign(Output, 'BSTR.OUT'); Rewrite(Output);
ReadLn(n);
FillChar(x, SizeOf(x), 0);
{C
u hình ban đu x
1
= x
2
= = x
n
:= 0}
repeat
{Thu
t toán sinh}
for i := 1 to n do Write(x[i]);
{In ra c
u hình hin ti}
WriteLn;
i := n;
{x
i
là ph
n t cui dãy, lùi dn i cho ti khi gp s 0 hoc khi i = 0 thì dng}

đó, ta có nhn xét nu x = {x
1
, x
2
, , x
k
} và x
1
< x
2
< < x
k
thì gii hn trên (giá tr ln nht có
th nhn) ca x
k
là n, ca x
k-1
là n - 1, ca x
k-2
là n - 2
C th: gii hn trên ca x
i
= n - k + i;
Còn tt nhiên, gii hn di ca x
i
(giá tr nh nht x
i
có th nhn) là x
i-1
+ 1.

, x
6
bng các gii hn di ca nó. Tc là:
• x
3
:= x
2
+ 1 = 4
• x
4
:= x
3
+ 1 = 5
• x
5
:= x
4
+ 1 = 6
• x
6
:= x
5
+ 1 = 7
Ta đc cu hình mi x = {1, 3, 4, 5, 6, 7} là cu hình k tip. Nu mun tìm tip, ta li nhn thy
rng x
6
= 7 cha đt gii hn trên, nh vy ch cn tng x
6
lên 1 là đc x = {1, 3, 4, 5, 6, 8}.
Vy k thut sinh tp con k tip t tp đã có x có th xây dng nh sau:

(1, 3, 4, 5, 6, 7)
Input: file vn bn SUBSET.INP cha hai s nguyên dng n, k (1 ≤ k ≤ n ≤ 30) cách nhau ít nht
mt du cách
Output: file vn bn SUBSET.OUT các tp con k phn t ca tp {1, 2, , n}
SUBSET.INP SUBSET.OUT
5 3 {1, 2, 3}
{1, 2, 4}
{1, 2, 5}
{1, 3, 4}
{1, 3, 5}
{1, 4, 5}
{2, 3, 4}
{2, 3, 5}
{2, 4, 5}
{3, 4, 5}
PROG02_2.PAS * Thut toán sinh lit kê các tp con k phn t
program Combinations;
const
max = 30;
var
x: array[1 max] of Integer;
n, k, i, j: Integer;
begin
{nh ngha li thit b nhp/xut chun}
Assign(Input, 'SUBSET.INP'); Reset(Input);
Assign(Output, 'SUBSET.OUT'); Rewrite(Output);
ReadLn(n, k);
for i := 1 to k do x[i] := i;
{x
1

u cha lùi đn 0 có ngha là cha phi cu hình kt thúc}
―― begin
Inc(x[i]); {Tng x
i
lên 1,
t các phn t đng sau x
i
b
ng gii hn di ca nó}
for j := i + 1 to k do x[j] := x[j - 1] + 1;
end;
until i = 0;
{Lùi
đn tn 0 có ngha là tt c các phn t đã đt gii hn trên - ht cu hình}
Close(Input); Close(Output);
end.
Bài toán lit kê
Lê Minh Hoàng
{ 9z
III. LIT KÊ CÁC HOÁN V
Ta s lp chng trình lit kê các hoán v ca {1, 2, , n} theo th t t đin.
Ví d vi n = 4, ta phi lit kê đ 24 hoán v:
1.1234 2.1243 3.1324 4.1342 5.1423 6.1432
7.2134 8.2143 9.2314 10.2341 11.2413 12.2431
13.3124 14.3142 15.3214 16.3241 17.3412 18.3421
19.4123 20.4132 21.4213 22.4231 23.4312 24.4321
Nh vy hoán v đu tiên s là (1, 2, , n). Hoán v cui cùng là (n, n-1, , 1).
Hoán v s sinh ra phi ln hn hoán v hin ti, hn th na phi là hoán v va đ ln hn hoán v
hin ti theo ngha không th có mt hoán v nào khác chen gia chúng khi sp th t.
Gi s hoán v hin ti là x = (3, 2, 6, 5, 4, 1), xét 4 phn t cui cùng, ta thy chúng đc xp gim

Ta có nhn xét gì qua ví d này: on cui ca hoán v đc xp gim dn, s x
5
= 4 là s nh nht
trong đon cui gim dn tho mãn điu kin ln hn x
2
= 2. Nu đi ch x
5
cho x
2
thì ta s đc x
2
= 4 và đon cui vn đc sp xp gim dn. Khi đó mun biu din nh nht cho các giá tr
trong đon cui thì ta ch cn đo ngc đon cui.
Trong trng hp hoán v hin ti là (2, 1, 3, 4) thì hoán v k tip s là (2, 1, 4, 3). Ta cng có th
coi hoán v (2, 1, 3, 4) có đon cui gim dn, đon cui này ch gm 1 phn t (4)
Vy k thut sinh hoán v k tip t hoán v hin ti có th xây dng nh sau:
• Xác đnh đon cui gim dn dài nht, tìm ch s i ca phn t x
i
đng lin trc đon cui đó.
iu này đng ngha vi vic tìm t v trí sát cui dãy lên đu, gp ch s i đu tiên tha mãn x
i
< x
i+1
. Nu toàn dãy đã là gim dn, thì đó là cu hình cui.
i := n - 1;
while (i > 0) and (x
i
> x
i+1
) do i := i - 1;

PERMUTE.INP PERMUTE.OUT
3 1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
Bài toán lit kê
Lê Minh Hoàng
{ 10z
PROG02_3.PAS * Thut toán sinh lit kê hoán v
program Permute;
const
max = 12;
var
n, i, k, a, b: Integer;
x: array[1 max] of Integer;
procedure Swap(var X, Y: Integer);
{Th
 tc đo giá tr hai tham bin X, Y}
var
Temp: Integer;
begin
Temp := X; X := Y; Y := Temp;
end;
begin
Assign(Input, 'PERMUTE.INP'); Reset(Input);
Assign(Output, 'PERMUTE.OUT'); Rewrite(Output);
ReadLn(n);
for i := 1 to n do x[i] := i;―

}
Swap(x[k], x[i]); {i ch x
k
và x
i
}
―――――― a := i + 1; b := n;
{L
t ngc đon cui gim dn, a: đu đon, b: cui đon}
―― while a < b do
begin
Swap(x[a], x[b]); {i ch x
a
và x
b
}
Inc(a);
{Ti
n a và lùi b, đi ch tip cho ti khi a, b chm nhau}
Dec(b);
end;
end;
until i = 0;―
{Toàn dãy là dãy gi
m dn - không sinh tip đc - ht cu hình}
Close(Input); Close(Output);
end.
Bài tp:
1. Các chng trình trên x lý không tt trong trng hp tm thng, đó là trng hp n = 0 đi
vi chng trình lit kê dãy nh phân cng nh trong chng trình lit kê hoán v, trng hp k = 0

sinh cng không nm ngoài nhn xét đó. Phng pháp sinh không th sinh ra đc cu hình th
p nu nh cha có cu hình th p - 1, chng t rng phng pháp sinh t ra u đim trong trng
hp lit kê toàn b mt s lng nh cu hình trong mt b d liu ln thì li có nhc đim và
ít tính ph dng trong nhng thut toán duyt hn ch. Hn th na, không phi cu hình ban đu
lúc nào cng d tìm đc, không phi k thut sinh cu hình k tip cho mi bài toán đu đn gin
nh trên (Sinh các chnh hp không lp chp k theo th t t đin chng hn). Ta sang mt chuyên
mc sau nói đn mt phng pháp lit kê có tính ph dng cao hn, đ gii các bài toán lit kê
phc tp hn đó là: Thut toán quay lui (Back tracking).
Bài toán lit kê
Lê Minh Hoàng
{ 12z
§
3. THUT TOÁN QUAY LUI
Thut toán quay lui dùng đ gii bài toán lit kê các cu hình. Mi cu hình đc xây dng
bng cách xây dng tng phn t, mi phn t đc chn bng cách th tt c các kh nng.
Gi thit cu hình cn lit kê có dng (x
1
, x
2
, , x
n
). Khi đó thut toán quay lui thc hin qua các
bc sau:
1) Xét tt c các giá tr x
1
có th nhn, th cho x
1
nhn ln lt các giá tr đó. Vi mi giá tr th
gán cho x
1

) bng cách th cho x
1
nhn ln lt các giá tr có th. Vi mi giá tr th gán cho x
1
li
lit kê tip cu hình n - 1 phn t (x
2
, x
3
, , x
n
).
Mô hình ca thut toán quay lui có th mô t nh sau:
{Th
 tc này th cho x
i
nh
n ln lt các giá tr mà nó có th nhn}
procedure Try(i: Integer);
begin
for (mi giá tr V có th gán cho x
i
) do
begin
<Th cho x
i
:= V>;
if (x
i
là phn t cui cùng trong cu hình) then

1
, x
2
, , x
n
). Ta s lit kê các dãy này bng cách th
dùng các giá tr {0, 1} gán cho x
i
. Vi mi giá tr th gán cho x
i
li th các giá tr có th gán cho
x
i+1
.Chng trình lit kê bng thut toán quay lui có th vit:
PROG03_1.PAS * Thut toán quay lui lit kê các dãy nh phân đ dài n
program BinaryStrings;
const
max = 30;
var
x: array[1 max] of Integer;
n: Integer;
procedure PrintResult;
{In c
u hình tìm đc, do th tc tìm đ quy
Try g
i khi tìm ra mt cu hì nh}
var
i: Integer;
begin
for i := 1 to n do Write(x[i]);

end;
end;
begin
Assign(Input, 'BSTR.INP'); Reset(Input);
Assign(Output, 'BSTR.OUT'); Rewrite(Output);
ReadLn(n);
{Nh
p d liu}
Try(1);
{Th
 các cách chn giá tr x
1
}
Close(Input);
Close(Output);
end.
Ví d: Khi n = 3, cây tìm kim quay lui nh sau:
Try(3)
Try(2)
Try(3) Try(3) Try(3)
Try(2)
Try(1)
x
1
:= 0
x
1
:= 1
x
2

:= 0
x
3
:= 1
000
001
010
011
100
101
110
111
result
Hình 2: Cây tìm kim quay lui trong bài toán lit kê dãy nh phân
Bài toán lit kê
Lê Minh Hoàng
{ 14z
II. LIT KÊ CÁC TP CON K PHN T
Input/Output có khuôn dng nh trong PROG02_2.PAS
 lit kê các tp con k phn t ca tp S = {1, 2, , n} ta có th đa v lit kê các cu hình (x
1
, x
2
,
, x
k
)  đây các x
i
∈ S và x
1

t 1 (=x
0
+ 1) đn n - k + 1, vi mi giá tr đó, xét tip tt
c các cách chn x
2
t x
1
+ 1 đn n - k + 2, c nh vy khi chn đc đn x
k
thì ta có mt cu
hình cn lit kê. Chng trình lit kê bng thut toán quay lui nh sau:
PROG03_2.PAS * Thut toán quay lui lit kê các tp con k phn t
program Combinations;
const
max = 30;
var
x: array[0 max] of Integer;
n, k: Integer;
procedure PrintResult;
(*In ra t
p con {x
1
, x
2
, , x
k
}*)
var
i: Integer;
begin

i
,  chng trình lit kê dãy nh phân ta
th chn các giá tr 0 hoc 1 còn  chng trình lit kê các tp con k phn t ta th chn x
i
là mt
trong các giá tr nguyên t x
i-1
+ 1 đn n - k + i. Qua đó ta có th thy tính ph dng ca thut toán
quay lui: mô hình cài đt có th thích hp cho nhiu bài toán, khác vi phng pháp sinh tun t,
vi mi bài toán li phi có mt thut toán sinh k tip riêng làm cho vic cài đt mi bài mt khác,
bên cnh đó, không phi thut toán sinh k tip nào cng d cài đt.
III. LIT KÊ CÁC CHNH HP KHÔNG LP CHP K
 lit kê các chnh hp không lp chp k ca tp S = {1, 2, , n} ta có th đa v lit kê các cu
hình (x
1
, x
2
, , x
k
)  đây các x
i
∈ S và khác nhau đôi mt.
Nh vy th tc Try(i) - xét tt c các kh nng chn x
i
- s th ht các giá tr t 1 đn n, mà các giá
tr này cha b các phn t đng trc chn. Mun xem các giá tr nào cha đc chn ta s dng
k thut dùng mng đánh du:
• Khi to mt mng c
1
, c

i
đã nhn mt giá tr khác ri thì các phn
t đng sau: x
i+1
, x
i+2
hoàn toàn có th nhn li giá tr j đó. iu này hoàn toàn hp lý trong
phép xây dng chnh hp không lp: x
1
có n cách chn, x
2
có n - 1 cách chn, Lu ý rng khi
th tc Try(i) có i = k thì ta không cn phi đánh du gì c vì tip theo ch có in kt qu ch
không cn phi chn thêm phn t nào na.
Input: file vn bn ARRANGES.INP cha hai s nguyên dng n, k (1 ≤ k ≤ n ≤ 20) cách nhau ít
nht mt du cách
Output: file vn bn ARRANGES.OUT ghi các chnh hp không lp chp k ca tp {1, 2, , n}
ARRANGES.INP ARRANGES.OUT
3 2 1 2
1 3
2 1
2 3
3 1
3 2
PROG03_3.PAS * Thut toán quay lui lit kê các chnh hp không lp chp k
program Arranges;
const
max = 20;
var
x: array[1 max] of Integer;

u đã chn đc đn xk thì ch vic in kt qu}
―― else
begin
c[j] := False; {ánh du: j đã b chn}
―――――――― Try(i + 1);
{Th
 tc này ch xét nhng giá tr còn t do gán cho x
i+1
, t
c là s không chn phi j}
―― c[j] := True;
{B
 đánh du: j li là t do, bi sp ti s th mt cách chn khác ca x
i
}
―――――――― end;
end;
end;
begin
Assign(Input, 'ARRANGES.INP'); Reset(Input);
Assign(Output, 'ARRANGES.OUT'); Rewrite(Output);
ReadLn(n, k);
FillChar(c, SizeOf(c), True);
{T
t c các s đu cha b chn}
Try(1);
{Th
 các cách chn giá tr ca x
1
}

3. Vì s phn t thc s ca mng x là không c đnh nên th tc PrintResult dùng đ in ra 1 cách
phân tích phi có thêm tham s cho bit s in ra bao nhiêu phn t.
4. Th tc đ quy Try(i) s th các giá tr có th nhn ca x
i
(x
i
≥ x
i - 1
)
5. Khi nào thì in kt qu và khi nào thì gi đ quy tìm tip ?
Lu ý rng t
i - 1
là tng ca tt c các phn t t x
1
đn x
i-1
do đó
• Khi t
i
= n tc là (x
i
= n - t
i - 1
) thì in kt qu
• Khi tìm tip, x
i+1
s phi ln hn hoc bng x
i
. Mt khác t
i+1

đc na.
Mt cách d hiu ta gi đ quy tìm tip khi giá tr x
i
đc chn còn cho phép chn thêm mt
phn t khác ln hn hoc bng nó mà không làm tng vt quá n. Còn ta in kt qu ch khi
x
i
mang giá tr đúng bng s thiu ht ca tng i-1 phn t đu so vi n.
6. Vy th tc Try(i) th các giá tr cho x
i
có th mô t nh sau: (đ tng quát cho i = 1, ta đt x
0
=
1 và t
0
= 0).
• Xét các giá tr ca x
i
t x
i - 1
đn (n - t
i-1
) div 2, cp nht t
i
:= t
i - 1
+ x
i
và gi đ quy tìm tip.
• Cui cùng xét giá tr x

procedure Init;
{Kh
i to}
begin
ReadLn(n);
x[0] := 1;
t[0] := 0;
end;
procedure PrintResult(k: Integer);
var
i: Integer;
begin
Write(n,' = ');
for i := 1 to k - 1 do Write(x[i], '+');
WriteLn(x[k]);
end;
procedure Try(i: Integer);
var
j: Integer;
begin
for j := x[i - 1] to (n - T[i - 1]) div 2 do
{Tr
ng hp còn chn tip x
i+1
}
begin
x[i] := j;
Bài toán lit kê
Lê Minh Hoàng
{ 18z

Vy mt nghim ca bài toán s đc bit khi ta tìm ra đc v trí ct ca nhng quân hu.
• Nu ta đnh hng ông (Phi), Tây (Trái), Nam (Di), Bc (Trên) thì ta nhn thy rng:
♦ Mt đng chéo theo hng ông Bc - Tây Nam (B-TN) bt k s đi qua mt s ô, các ô
đó có tính cht: Hàng + Ct = C (Const). Vi mi đng chéo B-TN ta có 1 hng s C và
vi mt hng s C: 2 ≤ C ≤ 2n xác đnh duy nht 1 đng chéo B-TN vì vy ta có th đánh
ch s cho các đng chéo B- TN t 2 đn 2n
♦ Mt đng chéo theo hng ông Nam - Tây Bc (N-TB) bt k s đi qua mt s ô, các ô
đó có tính cht: Hàng - Ct = C (Const). Vi mi đng chéo N-TB ta có 1 hng s C và
vi mt hng s C: 1 - n ≤ C ≤ n - 1 xác đnh duy nht 1 đng chéo N-TB vì vy ta có th
đánh ch s cho các đng chéo N- TB t 1 - n đn n - 1.
Bài toán lit kê
Lê Minh Hoàng
{ 19z
12345678
1
2
3
4
5
6
7
N
S
EW
8
Hình 4: ng chéo B-TN mang ch s 10 và đng chéo N-TB mang ch s 0, ô chung (5, 5)
Cài đt:
1. Ta có 3 mng logic đ đánh du:

Mng a[1 n]. a

4. Khi th đt đc quân hu th i vào ct j, nu đó là quân hu cui cùng (i = n) thì ta có mt
nghim. Nu không:
• Trc khi gi đ quy tìm cách đt quân hu th i + 1, ta đánh du ct và 2 đng chéo b quân
hu va đt khng ch (a
j
= b
i+j
= c
i-j
:= FALSE) đ các ln gi đ quy tip sau chn cách đt
các quân hu k tip s không chn vào nhng ô nm trên ct j và nhng đng chéo này na.

Sau khi gi đ quy tìm cách đt quân hu th i + 1, có ngha là sp ti ta li th mt cách đt
khác cho quân hu th i, ta b đánh du ct và 2 đng chéo b quân hu va th đt khng ch
(a
j
= b
i+j
= c
i-j
:= TRUE) tc là ct và 2 đng chéo đó li thành t do, bi khi đã đt quân hu i
sang v trí khác ri thì ct và 2 đng chéo đó hoàn toàn có th gán cho mt quân hu khác
Hãy xem li trong các chng trình lit kê chnh hp không lp và hoán v v k thut đánh du. 
đây ch khác vi lit kê hoán v là: lit kê hoán v ch cn mt mng đánh du xem giá tr có t do
không, còn bài toán xp hu thì cn phi đánh du c 3 thành phn: Ct, đng chéo B-TN,
đng chéo N- TB. Trng hp đn gin hn: Yêu cu lit kê các cách đt n quân xe lên bàn c
nxn sao cho không quân nào n quân nào chính là bài toán lit kê hoán v
Input: file vn bn QUEENS.INP cha s nguyên dng n ≤ 12
Output: file vn bn QUEENS.OUT, mi dòng ghi mt cách đt n quân hu
Bài toán lit kê

{M
i đng chéo ông Bc - Tây Nam đu t do}
――FillChar(c, SizeOf(c), True);
{M
i đng chéo ông Nam - Tây Bc đu t do}
end;
procedure PrintResult;
var
i: Integer;
begin
for i := 1 to n do Write('(', i, ', ', x[i], '); ');
WriteLn;
end;
procedure Try(i: Integer);
{Th
 các cách đt quân hu th i vào hàng i}
var
j: Integer;
begin
for j := 1 to n do
if a[j] and b[i + j] and c[i - j] then
{Ch
 xét nhng ct j mà ô (i, j)
ch
a
b
 khng ch}
――――――begin
x[i] := j;
{Th

nó s gi đ quy đ tìm tip x
i+1
có ngha là quá trình s duyt tin sâu xung phía di
đn tn nút lá, sau khi đã duyt ht các nhánh, tin trình lùi li th áp đt mt giá tr khác cho x
i
, đó
chính là ngun gc ca tên gi "thut toán quay lui"
Bài tp:
1. Mt s chng trình trên x lý không tt trong trng hp tm thng (n = 0 hoc k = 0), hãy
khc phc các li đó
2. Vit chng trình lit kê các chnh hp lp chp k ca n phn t
3. Cho hai s nguyên dng l, n. Hãy lit kê các xâu nh phân đ dài n có tính cht, bt k hai xâu
con nào đ dài l lin nhau đu khác nhau.
4. Vi n = 5, k = 3, v cây tìm kim quay lui ca chng trình lit kê t hp chp k ca tp {1, 2, ,
n}
5. Lit kê tt c các tp con ca tp S gm n s nguyên {S
1
, S
2
, , S
n
} nhp vào t bàn phím
6. Tng t nh bài 5 nhng ch lit kê các tp con có max - min ≤ T (T cho trc).
7. Mt dãy (x
1
, x
2
, , x
n
) gi là mt hoán v hoàn toàn ca tp {1, 2, , n} nu nó là mt hoán v và

i
s ng vi ch 2 nút tng ng vi 2 giá tr mà x
i+1

th nhn thì cây n cp s có ti 2
n
nút lá, con s này ln hn rt nhiu ln so vi d liu đu vào n.
Chính vì vy mà nu nh ta có thao tác tha trong vic chn x
i
thì s phi tr giá rt ln v chi phí
thc thi thut toán bi quá trình tìm kim lòng vòng vô ngha trong các bc chn k tip x
i+1
, x
i+2
,
Khi đó, mt vn đ đt ra là trong quá trình lit kê li gii ta cn tn dng nhng thông tin đã tìm
đc đ loi b sm nhng phng án chc chn không phi ti u. K thut đó gi là k thut
đánh giá nhánh cn trong tin trình quay lui.
III. MÔ HÌNH K THUT NHÁNH CN
Da trên mô hình thut toán quay lui, ta xây dng mô hình sau:
procedure Init;
begin
<Khi to mt cu hình bt k BESTCONFIG>;
end;
{Th tc này th chn cho x
i
tt c các giá tr nó có th nhn}
procedure Try(i: Integer);
begin
for (Mi giá tr V có th gán cho x

<Thông báo cu hình ti u BESTCONFIG>
end.
Bài toán lit kê
Lê Minh Hoàng
{ 23z
K thut nhánh cn thêm vào cho thut toán quay lui kh nng đánh giá theo tng bc, nu ti
bc th i, giá tr th gán cho x
i
không có hi vng tìm thy cu hình tt hn cu hình
BESTCONFIG thì th giá tr khác ngay mà không cn phi gi đ quy tìm tip hay ghi nhn kt
qu làm gì. Nghim ca bài toán s đc làm tt dn, bi khi tìm ra mt cu hình mi (tt hn
BESTCONFIG - tt nhiên), ta không in kt qu ngay mà s cp nht BESTCONFIG bng cu hình
mi va tìm đc
IV. BÀI TOÁN NGI DU LCH
Bài toán
Cho n thành ph đánh s t 1 đn n và m tuyn đng giao thông hai chiu gia chúng, mng li
giao thông này đc cho bi bng C cp nxn,  đây C
ij
= C
ji
= Chi phí đi đon đng trc tip t
thành ph i đn thành ph j. Gi thit rng C
ii
= 0 vi ∀i, C
ij
= +∞ nu không có đng trc tip t
thành ph i đn thành ph j.
Mt ngi du lch xut phát t thành ph 1, mun đi thm tt c các thành ph còn li mi thành
ph đúng 1 ln và cui cùng quay li thành ph 1. Hãy ch ra cho ngi đó hành trình vi chi phí ít
nht. Bài toán đó gi là bài toán ngi du lch hay bài toán hành trình ca mt thng gia

mi cách th chn x
2
nh vy thì x
3
có th chn mt trong các thành ph mà x
2
có đng đi ti
(ngoài x
1
). Tng quát: x
i
có th chn 1 trong các thành ph cha đi qua mà t x
i-1
có đng đi
trc tip ti.(1 ≤
i ≤ n)
3) Nhánh cn: Khi to cu hình BestConfig có chi phí = +∞. Vi mi bc th chn x
i
xem chi
phí đng đi cho ti lúc đó có < Chi phí ca cu hình BestConfig?, nu không nh hn thì th
giá tr khác ngay bi có đi tip cng ch tn thêm. Khi th đc mt giá tr x
n
ta kim tra xem x
n
có đng đi trc tip v 1 không ? Nu có đánh giá chi phí đi t thành ph 1 đn thành ph x
n
cng vi chi phí t x
n
đi trc tip v 1, nu nh hn chi phí ca đng đi BestConfig thì cp
nht li BestConfig bng cách đi mi.


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status