Tải bản đầy đủ (.pdf) (258 trang)

Le minh hoang bai giang cac chuyen de

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (4.21 MB, 258 trang )



{ 1z

Bài tốn li t kê

M CL 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. HỐN V ......................................................................................................................................................3
IV. T H P.........................................................................................................................................................3
§2. PH
NG PHÁP SINH (GENERATE) ............................................................................................ 5
I. SINH CÁC DÃY NH PHÂN
DÀI N.......................................................................................................6
II. LI T KÊ CÁC T P CON K PH N T ........................................................................................................7
III. LI T KÊ CÁC HOÁN V .............................................................................................................................9
§3. THU T TỐN QUAY LUI ............................................................................................................. 12
I. LI T KÊ CÁC DÃY NH PHÂN
DÀI N...............................................................................................13
II. LI T KÊ CÁC T P CON K PH N T ......................................................................................................14
III. LI T KÊ CÁC CH NH H P KHÔNG L P CH P K ..............................................................................15
IV. BÀI TỐN PHÂN TÍCH S .....................................................................................................................16
V. BÀI TỐN X P H U.................................................................................................................................18
§4. K THU T NHÁNH C N.............................................................................................................. 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

Lê Minh Hoàng


{ 2z

Bài tốn li t kê

§0. GI I THI U
Trong th c t , có m t s bài tố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 tốn đó g i là bài tốn đ m c u hình t
h p.
Trong l p các bài tốn đ m, có nh ng bài tốn cịn 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 tố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 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
Có th nói r ng, ph ng pháp li t kê là ph ng k cu i cùng đ gi i đ c m t s bài toán t h p
hi n nay. Khó kh n chính c a ph ng pháp này chính là s bùng n t h p.
xây d ng 1 t c u
hình (con s này khơng ph i là l n đ i v i các bài tốn t h p - Ví d li t kê các cách x p n≥13
ng i quanh m t bàn tròn) và gi thi t r ng m i thao tác xây d ng m t kho ng 1 giây, ta ph i m t
quãng 31 n m m i gi i xong. Tuy nhiên cùng v i s phát tri n c a máy tính đi n t , b ng ph ng
pháp li t kê, nhi u bài tốn t h p đã tìm th y l i gi i. Qua đó, ta c ng nên bi t r ng ch nên dùng
ph ng pháp li t kê khi khơng cịn m t ph ng pháp nào khác tìm ra l i gi i. Chính nh ng n
l c gi i quy t các bài toán th c t không dùng ph ng pháp li t kê đã thúc đ y s phát tri n c a

nhi u ngành toán h c.
Cu i cùng, nh ng tên g i sau đây, tuy v ngh a không ph i đ ng nh t, nh ng trong m t s tr ng
h p ng i ta có th dùng l n ngh a c a nhau đ c. ó là:
• Ph ng pháp li t kê
• Ph ng pháp vét c n trên t p ph ng án
• Ph ng pháp duy t toàn b

Lê Minh Hoàng


{ 3z

Bài tốn li t kê

§1. NH C L I M T S

KI N TH C

IS

T

H P

Cho S là m t t p h u h n g m n ph n t và k là m t s t nhiên.
G i X là t p các s nguyên d ng t 1 đ n k: X = {1, 2, ..., k}
I. CH NH H P L P
M i ánh x f: X → S. Cho t ng ng v i m i i ∈ X, m t và ch m t ph n t f(i) ∈ S.
c g i là m t ch nh h p l p ch p k c a S.
Nh ng do X là t p h u h n (k ph n t ) nên ánh x f có th xác đ nh qua b ng các giá tr f(1), f(2),

..., f(k).
Ví d : S = {A, B, C, D, E, F}; k = 3. M t ánh x f có th cho nh sau:
i
1
2
3
f(i)
E
C
E
Nên ng i ta đ ng nh t f v i dãy giá tr (f(1), f(2), ..., f(k)) và coi dãy giá tr này c ng là m t
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

An = nk
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
1
2
3
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 :

n!
A kn = n (n − 1)(n − 2)...(n − k + 1) =
(n − k )!
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 hốn v : (A, D, C, E, B, F) c a S = {A, B, C, D, E, F}
i
1
2
3
4
5
6
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
song ánh gi a {1, 2, ..., n} và S.
S hoán v c a t p g m n ph n t = s ch nh h p không l p ch p n:
Pn = n!
IV. T

H P


M t t p con g m k ph n t c a S đ
Lê Minh Hoàng

c g i là m t t h p ch p k c a S.


{ 4z

Bài toán li t kê

L y m t t p con k ph n t c a S, xét t t c k! hoán v c a t p con này. D th y r ng các hoán v đó
là các ch nh h p khơng l p ch p k c a S. Ví d l y t p {A, B, C} là t p con c a t p S trong ví d
trên thì: (A, B, C), (C, A, B), (B, C, A), ... là các ch nh h p không l p ch p 3 c a S. i u đó t c là
khi li t kê t t c các ch nh h p không l p ch p k thì m i t h p ch p k s đ c tính k! l n. V y:
S t h p ch p k c a t p g m n ph n t :
A kn
n!
C =
=
k! k!(n − k )!
k
n

S t p con c a t p n ph n t :
C 0n + C1n + ... + C nn = (1 + 1) n = 2 n

Lê Minh Hoàng



{ 5z

Bài tốn li t kê

§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 tố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ó>;
until <h t c u hình>;

ti p n u còn>;

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;

• Tính ph n x : a ≤ a
• Tính ph n đ i x ng: N u a ≤ b và b ≤ a thì b t bu c a = b.
• Tính b c c u: N u có a ≤ b và b ≤ c thì a ≤ c.
Trong tr ng h p a ≤ b và a ≠ b, ta dùng ký hi u "<" cho g n, (ta ng m hi u các ký hi u nh ≥, >,
kh i ph i đ nh ngh a)
Ví d nh quan h "≤" trên các s nguyên c ng nh trên các ki u vô h ng, li t kê là quan h th t
toàn ph n.
Trên các dãy h u h n, ng i ta c ng xác đ nh m t quan h th t :
Xét a = (a1, a2, ..., an) và b = (b1, b2, ..., bn); trên các ph n t c a a1, ..., an, b1, ..., bn đã có quan h
th t "≤". Khi đó a ≤ b n u nh
• Ho c ai = bi v i ∀i: 1 ≤ i ≤ n.
• Ho c t n t i m t s nguyên d ng k: 1 ≤ k < n đ :
=
b1
a1
a2
=
b2
...
ak-1 =
bk-1
ak
=
bk
ak+1 <
bk+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
thêm vào cu i dãy a ho c dãy b nh ng ph n t đ c bi t g i là ph n t ∅ đ đ dài c a a và b b ng

Lê Minh Hoàng


{ 6z

Bài toán li t kê

nhau, và coi nh ng ph n t ∅ này nh h n t t c các ph n t khác, ta l i đ a v xác đ nh th t t
đi n c a hai dãy cùng đ dài. Ví d :
• (1, 2, 3, 4) < (5, 6)
• (a, b, c) < (a, b, c, d)
• 'calculator' < 'computer'
I. SINH CÁC DÃY NH PHÂN Đ

DÀI N

M t dãy nh phân đ dài n là m t dãy x = x1x2...xn trong đó xi ∈ {0, 1} (∀i : 1 ≤ i ≤ n).
D th y: m t dãy nh phân x đ dài n là bi u di n nh phân c a m t giá tr nguyên p(x) nào đó n m
trong đo n [0, 2n - 1]. S các dãy nh phân đ dài n = s các s nguyên ∈ [0, 2n - 1] = 2n. Ta s l p
ch ng trình li t kê các dãy nh phân theo th t t đi n có ngh a là s li t kê l n l t các dãy nh
phân bi u di n các s nguyên theo th t 0, 1,..., 2n-1.
Ví d : Khi n = 3, các dãy nh phân đ dài 3 đ c li t kê nh sau:
p(x)
0
1
2
3
4
5
6

7
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 = (x1, x2, ...,
xn) 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ó:
c ng thêm 1:
Dãy m i:

10010000
+ 1

10010001

Dãy đang có:
c ng thêm 1:
Dãy m i:

10010111
+ 1


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.
i := n;
while (i > 0) and (xi = 1) do i := i - 1;
if i > 0 then
begin
xi := 1;
for j := i + 1 to n do xj := 0;
end;

D li u vào (Input): nh p t file v n b n BSTR.INP ch a s nguyên d ng n ≤ 30
K t qu ra(Output): ghi ra file v n b n BSTR.OUT các dãy nh phân đ dài n.
BSTR.INP
3

BSTR.OUT
000
001
010
011
100
101
110
111

PROG02_1.PAS * Thu t toán sinh li t kê các dãy nh
program Binary_Strings;

const
max = 30;
Lê Minh Hoàng

phân đ

dài n


{ 7z

Bài toán li t kê
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 x1 = x2 = ... = xn := 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;
{xi 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}

while (i > 0) and (x[i] = 1) do Dec(i);
if i > 0 then
{Ch a g p ph i c u hình 11...1}
begin
x[i] := 1;
{Thay xi b ng s 1}
FillChar(x[i + 1], (n - i) * SizeOf(x[1]), 0);
{ t xi + 1 = xi + 2 = ... = xn := 0}
end;
until i = 0;
{ ã h t c u hình}

{ óng thi t b nh p xu t chu n, th c ra khơng c n vì BP s t đ ng đóng Input và Output tr

c khi thốt ch

ng trình}

Close(Input); Close(Output);
end.

II. LI T KÊ CÁC T P CON K PH N T
Ta s l p ch ng trình li t kê các t p con k ph n t c a t p {1, 2, ..., n} theo th t t đi n
Ví d : v i n = 5, k = 3, ta ph i li t kê đ 10 t p con:
1.{1, 2, 3}
6.{1, 4, 5}

2.{1, 2, 4}
7.{2, 3, 4}


3.{1, 2, 5}
8.{2, 3, 5}

4.{1, 3, 4} 5.{1, 3, 5}
9.{2, 4, 5} 10.{3, 4, 5}

Nh v y t p con đ u tiên (c u hình kh i t o) là {1, 2, ..., k}.
C u hình k t thúc là {n - k + 1, n - k + 2, ..., n}.
Nh n xét: Ta s in ra t p con b ng cách in ra l n l t các ph n t c a nó theo th t t ng d n. T
đó, ta có nh n xét n u x = {x1, x2, ..., xk} và x1 < x2 < ... < xk thì gi i h n trên (giá tr l n nh t có
th nh n) c a xk là n, c a xk-1 là n - 1, c a xk-2 là n - 2...
C th : gi i h n trên c a xi = n - k + i;
Còn t t nhiên, gi i h n d i c a xi (giá tr nh nh t xi có th nh n) là xi-1 + 1.
Nh v y n u ta đang có m t dãy x đ i di n cho m t t p con, n u x là c u hình k t thúc có ngh a là
t t c các ph n t trong x đ u đã đ t t i gi i h n trên thì quá trình sinh k t thúc, n u khơng thì ta
ph i sinh ra m t dãy x m i t ng d n tho mãn v a đ l n h n dãy c theo ngh a khơng có m t t p
con k ph n t nào chen gi a chúng khi s p th t t đi n.
Ví d : n = 9, k = 6. C u hình đang có x = {1, 2, 6, 7, 8, 9}. Các ph n t x3 đ n x6 đã đ t t i gi i
h n trên nên đ sinh c u hình m i ta không th sinh b ng cách t ng m t ph n t trong s các x6, x5,
x4, x3 lên đ c, ta ph i t ng x2 = 2 lên thành x2 = 3.
c c u hình m i là x = {1, 3, 6, 7, 8, 9}. C u
hình này đã tho mãn l n h n c u hình tr c nh ng ch a tho mãn tính ch t v a đ l n mu n v y
ta l i thay x3, x4, x5, x6 b ng các gi i h n d i c a nó. T c là:
• x3 := x2 + 1 = 4
• x4 := x3 + 1 = 5
• x5 := x4 + 1 = 6
• x6 := x5 + 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 x6 = 7 ch a đ t gi i h n trên, nh v y ch c n t ng x6 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:

Lê Minh Hồng


{ 8z

Bài tốn li t kê



Tìm t cu i dãy lên đ u cho t i khi g p m t ph n t xi ch a đ t gi i h n trên n - k + i.
i := n;
while (i > 0) and (xi = n - k + i) do i := i - 1;

(1, 2, 6, 7, 8, 9);


N u tìm th y:
if i > 0 then

♦ T ng xi đó lên 1.
xi := xi + 1;



(1, 3, 6, 7, 8, 9)
t t t c các ph n t phía sau xi b ng gi i h n d i:
for j := i + 1 to k do xj := xj-1 + 1;

(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
5 3

SUBSET.OUT
{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;
{x1 := 1; x2 := 2; ... ; x3 := k (C u hình kh i t o)}
{Bi n đ m}
Count := 0;
――repeat
{In ra c u hình hi n t i}

Write('{');
for i := 1 to k - 1 do Write(x[i], ', ');
WriteLn(x[k], '}');
{Sinh ti p}

i := k;
{xi là ph n t cu i dãy, lùi d n i cho t i khi g p m t xi ch a đ t gi i h n trên n - k + i}
while (i > 0) and (x[i] = n - k + i) do Dec(i);
if i > 0 then―
{N 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 xi lên 1, t các ph n t đ ng sau xi 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.
Lê Minh Hoàng



{ 9z

Bài toán li t kê

III. LI T KÊ CÁC HỐ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
7.2134
13.3124
19.4123

2.1243
8.2143
14.3142
20.4132

3.1324
9.2314
15.3214
21.4213

4.1342
10.2341
16.3241
22.4231

5.1423
11.2413
17.3412

23.4312

6.1432
12.2431
18.3421
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 hốn v
hi n t i theo ngh a khơng th có m t hố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
d n, đi u đó có ngh a là cho dù ta có hốn v 4 ph n t này th nào, ta c ng đ c m t hoán v bé
h n hoán v hi n t i!. Nh v y ta ph i xét đ n x2 = 2, thay nó b ng m t giá tr khác. Ta s thay b ng
giá tr nào?, không th là 1 b i n u v y s đ c hốn v nh h n, khơng th là 3 vì đã có x1 = 3 r i
(ph n t sau không đ c ch n vào nh ng giá tr mà ph n t tr c đã ch n). Còn l i các giá tr 4, 5,
6. Vì c n m t hoán v v a đ l n h n hi n t i nên ta ch n x2 = 4. Còn các giá tr (x3, x4, x5, x6) s
l y trong t p {2, 6, 5, 1}. C ng vì tính v a đ l n nên ta s tìm bi u di n nh nh t c a 4 s này gán
cho x3, x4, x5, x6 t c là (1, 2, 5, 6). V y hoán v m i s là (3, 4, 1, 2, 5, 6).
(3, 2, 6, 5, 4, 1) → (3, 4, 1, 2, 5, 6).
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 x5 = 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 x2 = 2. N u đ i ch x5 cho x2 thì ta s đ c x2
= 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ì hốn v k ti p s là (2, 1, 4, 3). Ta c ng có th
coi hố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 hố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 xi đ 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 xi
< xi+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 (xi > xi+1) do i := i - 1;



Trong đo n cu i gi m d n, tìm ph n t xk nh nh t tho mãn đi u ki n xk > xi. Do đo n cu i
gi m d n, đi u này th c hi n b ng cách tìm t cu i dãy lên đ u g p ch s k đ u tiên tho mãn
xk > xi (có th dùng tìm ki m nh phân).

k := n;
while xk < xi do k := k - 1;


i ch xk và xi, l t ng c th t đo n cu i gi m d n (t xi+1 đ n xk) tr thành t ng d n.
Input: file v n b n PERMUTE.INP ch a s nguyên d ng n ≤ 12
Output: file v n b n PERMUTE.OUT các hoán v c a dãy (1, 2, ..., n)
PERMUTE.INP
3

Lê Minh Hoàng

PERMUTE.OUT
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ê


{ 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;―
{Kh i t o c u hình đ u: x1 := 1; x2 := 2; ..., xn := n}
――repeat
{In ra c u hình hốn v hi n t i}
――――for i := 1 to n do Write(x[i], ' ');
WriteLn;
i := n - 1;
while (i > 0) and (x[i] > x[i + 1]) do Dec(i);
if i > 0 then
{Ch a g p ph i hoán v cu i (n, n-1, ... ,1)}

――――――begin
{xk là ph n t cu i dãy}
k := n;
――――
while x[k] < x[i] do Dec(k);―
{Lùi d n k đ tìm g p xk đ u tiên l n h n xi }
Swap(x[k], x[i]);
{ i ch xk và xi}
―――――― 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 xa và xb}
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ê hốn v , tr ng h p k = 0
đ i v i ch ng trình li t kê t h p, hãy kh c ph c đi u đó.
2. Li t kê các dãy nh phân đ dài n có th coi là li t kê các ch nh h p l p ch p n c a t p 2 ph n t
{0, 1}. Hãy l p ch ng trình:

Nh p vào hai s n và k, li t kê các ch nh h p l p ch p k c a {0, 1, ..., n -1}.
G i ý: thay h c s 2 b ng h c s n.
3. Hãy li t kê các dãy nh phân đ dài n mà trong đó c m ch s "01" xu t hi n đúng 2 l n.
Bài t p:
4. Nh p vào m t danh sách n tên ng i. Li t kê t t c các cách ch n ra đúng k ng i trong s n
ng i đó.
G i ý: xây d ng m t ánh x t t p {1, 2, ..., n} đ n t p các tên ng i. Ví d xây d ng m t m ng
Tên: Tên[1] := 'Nguy n v n A'; Tên[2] := 'Tr n th B';.... sau đó li t kê t t c các t p con k ph n t

Lê Minh Hoàng


Bài toán li t kê

{ 11z

c a t p {1, 2, ..., n}. Ch có đi u khi in t p con, ta không in giá tr s {1, 3, 5} mà thay vào đó s in
ra {Tên[1], Tên [3], Tên[5]}. T c là in ra nh c a các giá tr tìm đ c qua ánh x
5. Li t kê t t c các t p con c a t p {1, 2, ..., n}. Có th dùng ph ng pháp li t kê t p con nh trên
ho c dùng ph ng pháp li t kê t t c các dãy nh phân. M i s 1 trong dãy nh phân t ng ng v i
m t ph n t đ c ch n trong t p. Ví d v i t p {1, 2, 3, 4} thì dãy nh phân 1010 s t ng ng v i
t p con {1, 3}. Hãy l p ch ng trình in ra t t c các t p con c a {1, 2, ..., n} theo hai ph ng pháp.
5. Nh p vào danh sách tên n ng i, in ra t t c các cách x p n ng i đó vào m t bàn
6. Nh p vào danh sách n ng i nam và n ng i n , in ra t t c các cách x p 2n ng i đó vào m t
bàn trịn, m i ng i nam ti p đ n m t ng i n .
7. Ng i ta có th dùng ph ng pháp sinh đ li t kê các ch nh h p không l p ch p k. Tuy nhiên có
m t cách là li t kê t t c các t p con k ph n t c a t p h p, sau đó in ra đ k! hốn v c a nó. Hãy
vi t ch ng trình li t kê các ch nh h p không l p ch p k c a {1, 2, ..., n}.
8. Li t kê t t c các hoán v ch cái trong t MISSISSIPPI theo th t t đi n.
9. Li t kê t t c các cách phân tích s nguyên d ng n thành t ng các s ngun d ng, hai cách

phân tích là hốn v c a nhau ch tính là m t cách.
Cu i cùng, ta có nh n xét, m i ph ng pháp li t kê đ u có u, nh c đi m riêng và ph ng pháp
sinh c ng không n m ngồ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 tốn quay lui (Back tracking).

Lê Minh Hồng


{ 12z

Bài tốn li t kê

§3. THU T TỐN QUAY LUI
Thu t toán quay lui dùng đ gi i bài tố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 (x1, x2,..., xn). Khi đó thu t tốn quay lui th c hi n qua các
b c sau:
1) Xét t t c các giá tr x1 có th nh n, th cho x1 nh n l n l t các giá tr đó. V i m i giá tr th
gán cho x1 ta s :
2) Xét t t c các giá tr x2 có th nh n, l i th cho x2 nh n l n l t các giá tr đó. V i m i giá tr
th gán cho x2 l i xét ti p các kh n ng ch n x3 ... c ti p t c nh v y đ n b c:
n) Xét t t c các giá tr xn có th nh n, th cho xn nh n l n l t các giá tr đó, thơng báo c u hình
tìm đ c (x1, x2, ..., xn).
Trên ph ng di n quy n p, có th nói r ng thu t tốn quay lui li t kê các c u hình n ph n t d ng

(x1, x2, .., xn) b ng cách th cho x1 nh n l n l t các giá tr có th . V i m i giá tr th gán cho x1 l i
li t kê ti p c u hình n - 1 ph n t (x2, x3, ..., xn).
Mơ hình c a thu t tốn quay lui có th mơ t nh sau:
{Th t c này th cho xi 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 xi) do
begin
<Th cho xi := V>;
if (xi là ph n t cu i cùng trong c u hình) then
<Thơng báo c u hình tìm đ c>
else
begin
<Ghi nh n vi c cho xi nh n giá tr V (N u c n)>;
Try(i + 1); {G i đ quy đ ch n ti p xi+1}
――
end;
end;
end;

khác>;

Thu t toán quay lui s b t đ u b ng l i g i Try(1)
Ta có th trình bày q trình tìm ki m l i gi i c a thu t tốn quay lui b ng cây sau:
Try(1)


Try(2)

Try(3)

Try(2)

Try(3)

Try(3)

Hình 1: Cây tìm ki m quay lui

Lê Minh Hồng

Try(3)


{ 13z

Bài toán li t kê

I. LI T KÊ CÁC DÃY NH PHÂN Đ

DÀI N

Input/Output v i khuôn d ng nh trong PROG2_1.PAS
Bi u di n dãy nh phân đ dài N d i d ng (x1, x2, ..., xn). 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 xi. V i m i giá tr th gán cho xi l i th các giá tr có th gán cho
xi+1.Ch ng trình li t kê b ng thu t tốn quay lui có th vi t:
phân đ


PROG03_1.PAS * Thu t toán quay lui li t kê các dãy nh
program BinaryStrings;
const
max = 30;
var
x: array[1..max] of Integer;
n: Integer;
procedure PrintResult;
{In c u hình tìm đ
var
i: Integer;
begin
for i := 1 to n do Write(x[i]);
WriteLn;
end;
procedure Try(i: Integer);
var
j: Integer;
begin
for j := 0 to 1 do
――――begin
x[i] := j;
if i = n then PrintResult
―――― else Try(i + 1);
end;
end;

dài n


c, do th t c tìm đ quy Try g i khi tìm ra m t c u hình}

{Th các cách ch n xi}

{Xét các giá tr có th gán cho xi, v i m i giá tr đó}
{Th đ t xi}
{N u i = n thì in k t qu }
{N u i ch a ph i là ph n t cu i thì tìm ti p xi+1}

begin
Assign(Input, 'BSTR.INP'); Reset(Input);
Assign(Output, 'BSTR.OUT'); Rewrite(Output);
{Nh p d li u}
ReadLn(n);
Try(1);
{Th các cách ch n giá tr x1}
Close(Input);
Close(Output);
end.

Ví d : Khi n = 3, cây tìm ki m quay lui nh sau:
Try(1)
x1 := 0

x1 := 1

Try(2)
x2 := 0

Try(3)

x3 := 0

000

x3 := 1

001

Try(2)

x2 := 1

x2 := 0

Try(3)
x3 := 0

010

Try(3)

x3 := 1

011

x3 := 0

100

x2 := 1


Try(3)

x3 := 1

101

x3 := 0

x3 := 1

110

Hình 2: Cây tìm ki m quay lui trong bài toán li t kê dãy nh phân
Lê Minh Hoàng

111

result


Bài toán li t kê

{ 14z

II. LI T KÊ CÁC T P CON K PH N T
Input/Output có khn 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 (x1, x2,
..., xk) đây các xi ∈ S và x1 < x2 < ... < xk. Ta có nh n xét:
• xk ≤ n

• xk-1 ≤ xk - 1 ≤ n - 1
• ...
• xi ≤ n - k + i
• ...
• x1 ≤ n - k + 1.
T đó suy ra xi-1 + 1 ≤ xi ≤ n - k + i (1 ≤ i ≤ k) đây ta gi thi t có thêm m t s x0 = 0 khi xét i = 1.
Nh v y ta s xét t t c các cách ch n x1 t 1 (=x0 + 1) đ n n - k + 1, v i m i giá tr đó, xét ti p t t
c các cách ch n x2 t x1 + 1 đ n n - k + 2,... c nh v y khi ch n đ c đ n xk 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 {x1, x2, ..., xk}*)
var
i: Integer;
begin
Write('{');
for i := 1 to k - 1 do Write(x[i], ', ');
WriteLn(x[k], '}');
end;
procedure Try(i: Integer); {Th các cách ch n giá tr cho x[i]}
var
j: Integer;
begin
for j := x[i - 1] + 1 to n - k + i do
begin

x[i] := j;
if i = k then PrintResult
else Try(i + 1);
end;
end;
begin
Assign(Input, 'SUBSET.INP'); Reset(Input);
Assign(Output, 'SUBSET.OUT'); Rewrite(Output);
ReadLn(n, k);
x[0] := 0;
Try(1);
Close(Input); Close(Output);
end.

Lê Minh Hoàng


{ 15z

Bài toán li t kê

N u đ ý ch ng trình trên và ch ng trình li t kê dãy nh phân đ dài n, ta th y v c b n chúng
ch khác nhau th t c Try(i) - ch n th các giá tr cho xi, 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 xi là m t
trong các giá tr nguyên t xi-1 + 1 đ n n - k + i. Qua đó ta có th th y tính ph d ng c a thu t tốn
quay lui: mơ hình cài đ t có th thích h p cho nhi u bài tốn, khác v i ph ng pháp sinh tu n t ,
v i m i bài tố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 (x1, x2, ..., xk) đây các xi ∈ 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 xi - 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 c1, c2, ..., cn mang ki u logic. đây ci cho bi t giá tr i có cịn t do hay đã
b ch n r i. Ban đ u kh i t o t t c các ph n t m ng c là TRUE có ngh a là các ph n t t 1
đ n n đ u t do.
• T i b c ch n các giá tr có th c a xi ta ch xét nh ng giá tr j có cj = TRUE có ngh a là ch
ch n nh ng giá tr t do.
• Tr c khi g i đ quy tìm xi+1: ta đ t giá tr j v a gán cho xi là đã b ch n có ngh a là đ t cj :=
FALSE đ các th t c Try(i + 1), Try(i + 2)... g i sau này không ch n ph i giá tr j đó n a
• Sau khi g i đ quy tìm xi+1: có ngh a là s p t i ta s th gán m t giá tr khác cho xi thì ta s đ t
giá tr j v a th đó thành t do (cj := TRUE), b i khi xi đã nh n m t giá tr khác r i thì các ph n
t đ ng sau: xi+1, xi+2 ... hồn tồn có th nh n l i giá tr j đó. i u này hồn tồn h p lý trong
phép xây d ng ch nh h p khơng l p: x1 có n cách ch n, x2 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
3 2

ARRANGES.OUT
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;
c: array[1..max] of Boolean;
n, k: Integer;
procedure PrintResult;
Lê Minh Hoàng

{Th t c in c u hình tìm đ

c}


{ 16z

Bài toán li t kê
var
i: Integer;
begin
for i := 1 to k do Write(x[i],' ');
WriteLn;
end;

procedure Try(i: Integer); {Th các cách ch n xi}
var
j: Integer;

begin
for j := 1 to n do
if c[j] then
{Ch xét nh ng giá tr j còn t do}
begin
x[i] := j;
if i = k then PrintResult {N 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 xi+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 xi}
―――――――― 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 x1}
Close(Input); Close(Output);
end.


Nh n xét: khi k = n thì đây là ch

ng trình li t kê hốn v

IV. BÀI TỐN PHÂN TÍCH S
Bài tốn
Cho m t s ngun d ng n ≤ 30, hãy tìm t t c các cách phân tích s n thành t ng c a các s
ngun d ng, các cách phân tích là hốn v c a nhau ch tính là 1 cách.
Cách làm:
1. Ta s l u nghi m trong m ng x, ngồi ra có m t m ng t. M ng t xây d ng nh sau: ti s là t ng
các ph n t trong m ng x t x1 đ n xi: ti := x1 + x2 + ... + xi.
2. Khi li t kê các dãy x có t ng các ph n t đúng b ng n, đ tránh s trùng l p ta đ a thêm ràng
bu c xi-1 ≤ xi.
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 xi (xi ≥ xi - 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 ti - 1 là t ng c a t t c các ph n t t x1 đ n xi-1 do đó
• Khi ti = n t c là (xi = n - ti - 1) thì in k t qu
• Khi tìm ti p, xi+1 s ph i l n h n ho c b ng xi. M t khác ti+1 là t ng c a các s t x1 t i xi+1
không đ c v t quá n. V y ta có ti+1 ≤ n ⇔ ti-1 + xi + xi+1 ≤ n ⇔ xi + xi + 1 ≤ n - ti - 1 t c là xi

Lê Minh Hoàng


{ 17z

Bài toán li t kê

≤ (n - ti - 1)/2. Ví d đ n gi n khi n = 10 thì ch n x1 = 6, 7, 8, 9 là vi c làm vơ ngh a vì nh

v y c ng không ra nghi m mà c ng không ch n ti p x2 đ c n a.
M t cách d hi u ta g i đ quy tìm ti p khi giá tr xi đ 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 q n. Cịn ta in k t qu ch khi
xi 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 xi có th mơ t nh sau: (đ t ng quát cho i = 1, ta đ t x0 =
1 và t0 = 0).
• Xét các giá tr c a xi t xi - 1 đ n (n - ti-1) div 2, c p nh t ti := ti - 1 + xi và g i đ quy tìm ti p.
• Cu i cùng xét giá tr xi = n - ti-1 và in k t qu t x1 đ n xi.
Input: file v n b n ANALYSE.INP ch a s nguyên d ng n ≤ 30
Output: file v n b n ANALYSE.OUT ghi các cách phân tích s n.
ANALYSE.INP
6

ANALYSE.OUT
6 = 1+1+1+1+1+1
6 = 1+1+1+1+2
6 = 1+1+1+3
6 = 1+1+2+2
6 = 1+1+4
6 = 1+2+3
6 = 1+5
6 = 2+2+2
6 = 2+4
6 = 3+3
6 = 6

PROG03_4.PAS * Thu t toán quay lui li t kê các cách phân tích s
program Analyses;
const
max = 30;

var
n: Integer;
x: array[0..max] of Integer;
t: array[0..max] of Integer;
procedure Init;
begin
ReadLn(n);
x[0] := 1;
t[0] := 0;
end;

{Kh i t o}

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
begin
x[i] := j;

Lê Minh Hồng


{Tr

ng h p cịn ch n ti p xi+1}


{ 18z

Bài toán li t kê
t[i] := t[i - 1] + j;
Try(i + 1);
end;
x[i] := n - T[i - 1];
{N u xi là ph n t cu i thì nó b t bu c ph i là ... và in k t qu }
PrintResult(i);
end;
begin
Assign(Input, 'ANALYSE.INP'); Reset(Input);
Assign(Output, 'ANALYSE.OUT'); Rewrite(Output);
Init;
Try(1);
Close(Input);
Close(Output);
end.

Bây gi ta xét ti p m t ví d kinh đi n c a thu t tốn quay lui:
V. BÀI TỐN X P H U
Bài tốn
Xét bàn c t ng qt kích th c nxn. M t quân h u trên bàn c có th n đ c các quân khác n m
t i các ô cùng hàng, cùng c t ho c cùng đ ng chéo. Hãy tìm các x p n quân h u trên bàn c sao

cho không quân nào n quân nào.
Ví d m t cách x p v i n = 8:

Hình 3: X p 8 quân h u trên bàn c 8x8

Phân tích
Rõ ràng n quân h u s đ c đ t m i con m t hàng vì h u n đ c ngang, ta g i quân h u s đ t
hàng 1 là quân h u 1, quân h u hàng 2 là quân h u 2... quân h u hàng n là quân h u n.
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.


Lê Minh Hồng



×