15
LP TRÌNH = ++THUT TOÁN S 2, 15 - 1 - 2012 Nguyn Hu Đin http://nhdien.wordpress.com Email:[email protected] Mobile: 0989 061 951 PROGRAMMING ALGORITHM HANOI Gii thiu Bn th nghim cho các bn yêu thích lp trình ph thông và thi Olympic tin hc. Tôi có ý đnh lp tp chí đin t vi tên như trên (lp trang web riêng), ni dung các bài ging lp trình và các  bài thi hay. Mi các bn tham gia và cho ý kin. Nhng bài tp sau đây đưc ly t tài liu sưu tm trên mng đưc biên tp và sa đi li vi ni dung áp dng các phương pháp gii ca tin hc. Các bn có các bài hay, sưu tm hay gi cho tôi đ tôi đưa vào danh sách vi tên chú thích ca bn hoc bn sưu tm. C gng c 15 ngày tôi ra mt  bn đ lưu tr. Mi thc mc và yêu cu liên h vi: Nguyn Hu Đin Hanoi University of Science Center for High-Perf ormance Computing 334 Nguyen Trai, Thanh Xuan, Hanoi Office (84-4) 557 2869 Danh sách bài knày Bài 2.1 Kh u vưn . . . . . . . . . . . . . . . . . 1 Bài 2.2 Dã y tru ng bình . . . . . . . . . . . . . . 3 Bài 2.3 Hàn h trình qua núi . . . . . . . . . . . 5 Bài 2.4 Ngày sin h nh t . . . . . . . . . . . . . . 7 Bài 2.5 T chơi ct hình ch nht . . . . . . . 9 Bài 2.6 Các dòng sôn g . . . . . . . . . . . . . . 12 Danh sách chương trình 1 gar .pas . . . . . . . . . . . . . . . . . . . . 3 2 mean.pas . . . . . . . . . . . . . . . . . . . 4 3 mou.c . . . . . . . . . . . . . . . . . . . . . 6 4 bir.c . . . . . . . . . . . . . . . . . . . . . . 8 5 rec.pas . . . . . . . . . . . . . . . . . . . . 12 6 riv .pas . . . . . . . . . . . . . . . . . . . . . 14 The 17th International Olympiad in Nowy Sacz, Poland, 2005 Bài 2.1 (Khu vưn) File ngun gar.* B nh cho phép: 32MB. Thi gian chy ti đa: 0.5s. Byteman trng n cây hoa hng trong khu vưn ca mình - khu vưn đưc coi là đp nht Th trn Tin hc vi nhng bông hoa n tht to và đp khi hè v. Byteman thy rng mình không th chăm sóc tt c hoa hng trong vưn, vì th ông đã quyt đnh thuê thêm hai ngưi làm vưn. Ông mun chn hai vùng hình ch nht trong vưn đ phân cho hai ngưi làm vưn chăm sóc hoa hng trên đó. Các phn vưn này đưc tách ri nhau và trên mi  phn có k cây hoa hng. Byteman mun dng hàng rào xung quanh các vùng ch nht đó, nhưng ông không có nhiu tin vì vy ông mun dng đưc hàng rào càng nh càng tt. Nhim v ca bn là giúp ông chn hai vùng ch nht này đ rào. Khu vưn có dng mt hình ch nht vi chiu dài L mét và chiu rng W mét, đưc chia thành L.W hình vuông vi kích thưc 1 mét x 1 mét mi hình. Ta đưa vào mt h ta đ có các trc song song vi các cnh ca khu vưn. Tt c các hình vuông có các ta đ nguyên ( x, y) tha mãn 1 x L,1  y W . Mi hình vuông có th cha mt s bt kcác cây hoa hng.  Hình ch nht đưc chn đ rào có các cnh song so ng v i cá c c nh c a khu v ư n , các hì nh vu ôn g trong các góc c a chúng đ u có t a đ nguyên. Cho 1 L 1 L 2 L;1 W 1 W 2 W , vùng hình ch nht đưc chn vi các góc có ta đ ( L 1 , W 1 ), ( L 1 , W 2 ), ( L 2 , W 1 ), v( L 2 , W 2 ) s: - Cha tt c các hình vuông vi ta đ (x,y) tha mãn L 1 x L 2 W 1  y W 2 - Có chu vi là 2( L 2 L 1 + 1) + 2.(W 2 W 1 + 1).

laptrinh-02-2012

Embed Size (px)

Citation preview

Page 1: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 1/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

Nguyn Hu Đinhttp://nhdien.wordpress.com

Email:[email protected]: 0989 061 951

PROGRAMMING

ALGORITHM

HANOI

Gii thiuBn th nghim cho các bn yêu thích lp trìnhph thông và thi Olympic tin hc. Tôi có ý đnhlp tp chí đin t vi tên như trên (lp trangweb riêng), ni dung các bài ging lp trình và các

 bài thi hay. Mi các bn tham gia và cho ý kin.Nhng bài tp sau đây đưc ly t tài liu sưu

tm trên mng đưc biên tp và sa đi li vi nidung áp dng các phương pháp gii ca tin hc.Các bn có các bài hay, sưu tm hay gi cho tôi đ tôi đưa vào danh sách vi tên chú thích ca bnhoc bn sưu tm. C gng c 15 ngày tôi ra mt

 bn đ lưu tr. Mi thc mc và yêu cu liên hvi:

Nguyn Hu ĐinHanoi University of ScienceCenter for High-Performance Computing

334 Nguyen Trai, Thanh Xuan, HanoiOffice (84-4) 557 2869

Danh sách bài kỳ này

Bài 2.1 Khu vưn . . . . . . . . . . . . . . . . . 1Bài 2.2 Dãy trung bình . . . . . . . . . . . . . . 3Bài 2.3 Hành trình qua núi . . . . . . . . . . . 5Bài 2.4 Ngày sinh nht . . . . . . . . . . . . . . 7

Bài 2.5 Trò chơi ct hình ch nht . . . . . . . 9Bài 2.6 Các dòng sông . . . . . . . . . . . . . . 12

Danh sách chương trình

1 gar.pas . . . . . . . . . . . . . . . . . . . . 32 mean.pas . . . . . . . . . . . . . . . . . . . 43 mou.c . . . . . . . . . . . . . . . . . . . . . 64 bir.c . . . . . . . . . . . . . . . . . . . . . . 85 rec.pas . . . . . . . . . . . . . . . . . . . . 12

6 riv.pas . . . . . . . . . . . . . . . . . . . . . 14

The 17th International Olympiad in Nowy Sacz, Poland, 2005

Bài 2.1 (Khu vưn)File ngun gar.*B nh cho phép: 32MB. Thi gian chy ti đa: 0.5s.

Byteman trng n cây hoa hng trong khu vưn ca

mình - khu vưn đưc coi là đp nht Th trn Tin hcvi nhng bông hoa n tht to và đp khi hè v. Bytemanthy rng mình không th chăm sóc tt c hoa hng trongvưn, vì th ông đã quyt đnh thuê thêm hai ngưi làmvưn. Ông mun chn hai vùng hình ch nht trong vưnđ phân cho hai ngưi làm vưn chăm sóc hoa hng trênđó. Các phn vưn này đưc tách ri nhau và trên mi phn có k cây hoa hng.

Byteman mun dng hàng rào xung quanh các vùng

ch nht đó, nhưng ông không có nhiu tin vì vy ôngmun dng đưc hàng rào càng nh càng tt. Nhim vca bn là giúp ông chn hai vùng ch nht này đ rào.

Khu vưn có dng mt hình ch nht vi chiu dàiL mét và chiu rng W  mét, đưc chia thành L.W  hìnhvuông vi kích thưc 1 mét x 1 mét mi hình. Ta đưa vàomt h ta đ có các trc song song vi các cnh ca khu

vưn. Tt c các hình vuông có các ta đ nguyên (x, y)tha mãn 1 ≤ x ≤ L, 1 ≤  y ≤ W . Mi hình vuông có th cha mt s bt kỳ các cây hoa hng.

 Hình ch nht đưc chn đ rào có các cnh songsong vi các cnh ca khu vưn, các hình vuôngtrong các góc ca chúng đu có ta đ nguyên. Cho1 ≤ L1 ≤ L2 ≤ L; 1 ≤ W 1 ≤ W 2 ≤ W ,

vùng hình ch nht đưc chn vi các góc có ta đ là(L1,W 1), (L1,W 2), (L2,W 1), v(L2,W 2) s:

- Cha tt c các hình vuông vi ta đ (x,y) tha mãnL1 ≤ x ≤ L2 và W 1 ≤  y ≤W 2 và

- Có chu vi là 2(L2 − L1 + 1) + 2.(W 2 −W 1 + 1).

Page 2: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 2/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

 Hai vùng ch nht phi tách ri nhau, tc là chúngkhông cha mt hình vuông chung nào. Thm chí nuchúng có mt cnh chung hoc mt phn ca nó, chúngcũng phi đưc bao xung quanh bi các hàng rào riêng r.

 Nhim v: Vit chương trình:

- Đc t input chun kích thưc ca khu vưn, s câyhoa hng trong khu vưn, s cây hoa hng trong mi vùnghình ch nht và v trí ca các cây hoa.

- Tìm hai hình ch nht tha mãn điu kin đ bài vitng các chu vi là nh nht.

- Vit ra output chun tng nh nht các chu vi ca haihình ch nht riêng r, mi hình cha chính xác s cây hoahng (hoc ghi ra t NO, nu không có các cp hình ch 

nht nào tn ti).Đnh dng tp vào: Dòng đu tiên ca input chuncha hai s nguyên: L và W (1 ≤ L,W  ≤ 250) cáchnhau bi mt du trng - mô t chiu dài và chiurng ca khu vưn. Dòng th hai cha hai s nguyên:n, k(2 ≤ n ≤ 5000, 1 ≤ k ≤ n/2)cách nhau bi mtdu trng - mô t s các cây hoa trong vưn và s cáccây hoa có trong mi min ch nht đưc chn. n dòngtip theo cha ta đ ca các cây hoa hng, mi dòng chata đ ca mt cây. Dòng th (i + 2) cha hai s nguyênLi,W i(1 ≤ Li ≤ L, 1 ≤ W i ≤ W ) cách nhau bi mt dutrng - mô t ta đ ca hình vuông cha cây hoa hngth i. Hai hoc nhiu hơn cây hoa hng có th đưc đttrong cùng mt ô vuông. Trong 50% test, kích thưc cakhu vưn tha mãn L,W ≤ 40.

Đnh dng tp ra: Kt qu ghi ra file OUTPUT trên mtdòng vi ch mt s nguyên - mô t tng nh nht các chuvi min ch nht riêng r này, mi min có cha chính xáck cây hoa hng, hoc ghi ra t “NO”, nu không có cp

hình ch nht nào tn ti.

Ví d.

input.inp output.out6 5

7 3

3 4

3 3

6 1

1 1

5 5

5 53 1

22

1 2 3 4 5 6

 Hình 1: vd

Li gii 2.1. Phân tích. Gi Ax, y là s cây hoa

trong ô (x, y).

Gi Rx, y là s tng s cây hoa nm trong khonghình ch nht ô trái dưi là (1, 1) ô phi trên là (x, y).

Ta s tính đưc Rxy theo công thc:- Rx, y = 0 vi (x = 0hocy = 0)

- Rx, y = Rx−1, y−1 − Rx, y−1 − Rx−1, y + Ax, y

Như vy ta có th tính s hoa nm trong khonghình ch nht vi ô trái dưi là (x1, y1), ô phi trên là(x2, y2) trong O(1) theo công thc:

Rx2, y2 − Rx2, y1−1 − Rx1−1, y2 + Rx1−1, y1−1

Đ qua đưc 50% s test, bn ch cn duyt cáccnh ca 2 hình ch nht (đ phc tp là O(w4l4).Nhưng đ qua đưc ht tt c các test, bn cn phicó mt thut toán tt hơn như sau:

Ta có nhn xét là 2 hình ch nht không giaonhau thì s tn ti ít nht mt đưng thng (nganghoc dc) chia mnh vưn thành 2 phn trong đó miphn có mt hình ch nht đưc chn.

Như vy, ta s duyt mi hình ch nht tha mãntrong đó có k cây hoa. Nhưng vi thut toán duytO(w2l2) s không đáp ng đưc thi gian, vì vy tacó mt cách duyt tt hơn như sau:

Duyt 2 cnh trên ( y2) và dưi ( y1) ca hình chnht. Chúng ta s xét các hình ch nht có 2 cnh nhưtha mãn điu kin đó. Vi nhng hình ch nht cócnh trái x1, cnh phi x2 ta s xét các trưng hp sau:

-Nuslưnghoa = k thì ghi nhn hình ch nht

(x1, y1, x2, y2)

- Nu s lưng hoa < k thì tăng x2.

- Nu s lưng hoa > k thì tăng x1.

Nguyn Hu Đin 2/15 http://nhdien.wordpress.com

Page 3: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 3/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

Như vy thut toán duyt s có đ phc tp (w2l).Các phn còn li ch là các bưc đơn gin.

Dưi đây là chương trình đã đưc 100 đim ca bài toán này trong online contest.

Phương án cài đt

Chương trình 1: gar.pas

1 const2 max = 251;3 INF = $3F3F3F3F; {$}

5 var6 fi , fo: text;7 m, n, k : longint ;8 cot, a: array [0.. max, 0..max] of  longint ;9 dai , left , right , up, down: array [0.. max] of  longint ;

11 procedure read_data;12 var p, x, y, i : longint ;13 begin14 readln(n, m);15 readln(p, k);16 for i := 1 to p do17 begin18 readln(y, x);19 inc(a[x, y]);20 end;21 end;

23 procedure init;24 var i , j , u, v: longint ;25 begin26 fillchar ( left , sizeof ( left ) , $3F);27 fillchar ( right , sizeof ( right ), $3F);28 fillchar (up, sizeof (up), $3F);29 fillchar (down,sizeof (down), $3F);30 for i := 1 to m do31 for j := 1 to n do32 cot[ i , j ] := cot[ i − 1, j] + a[i, j ];33 end;

35 procedure update(x, y, i , j : longint );36 var p: longint ;37 begin38 p := 2 ∗ (y − x + 1) + 2 ∗ (j − i + 1);39 if  down[x] > p then down[x] := p;40 if  up[y] > p then up[y] := p;41 if  right [ i ] > p then right[i] := p;42 if  left [j ] > p then left[j] := p;43 end;

45 procedure process;46 var s, i , j , x, y: longint ;

47 begin48 for x := 1 to m do49 for y := x to m do50 begin51 for i := 1 to n do52 dai[ i ] := cot[y, i ] − cot[x − 1, i ];

53 i := 1;54 j := i ;55 s := dai [1];56 while i <= n do57 begin58 while (s < k) and (j < n) do59 begin60 inc(j);61 s := s + dai[j ];62 end;63 if  s = k then update(x, y, i , j) ;64 s := s − dai[ i ];65 inc(i);

66 end;67 end;

69 procedure write_result;70 var i , best: longint ;71 begin72 for i := 2 to n do73 if  left [ i − 1] < left [ i ] then74 left [i] := left [i − 1];75 for i := n − 1 downto 1 do76 if  right [ i ] > right[ i + 1] then77 right [ i ] := right [ i + 1];

78 for i := 2 to m do79 if  up[i ] > up[i − 1] then80 up[i] := up[i − 1];81 for i := m − 1 downto 1 do82 if  down[i] > down[i + 1] then83 down[i] := down[i + 1];

85 best := INF + INF − 1;86 for i := 1 to n − 1 do87 if  left [ i ] + right[ i + 1] < best then88 best := left [i] + right[i + 1];89 for i := 1 to m − 1 do90 if  up[i ] + down[i + 1] < best then91 best := up[i ] + down[i + 1];92 if  best < INF + INF − 1 then93 writeln(best) else writeln(’NO’);94 end;

96 begin97 read_data;98 init ;99 process ;

100 write_result ;101 end.

Bài 2.2 (Dãy trung bình)

Nguyn Hu Đin 3/15 http://nhdien.wordpress.com

Page 4: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 4/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

File ngun mea.*B nh cho phép: 16MB. Thi gian chy ti đa: 5s.

Gi s ta có dãy s nguyên không gims1, . . . , sn+1(si ≤ si+1vi1 ≤ i ≤ n). Dãy s m1, . . . ,mn

đưc xác đnh theo quy tc:mi = 1

2(si + si+1) vi 1 ≤ i ≤ n, đưc gi là dãy trungbình ca dãy s1, ..., sn+1.

Thí d: Dãy trung bình ca dãy s 1, 2, 2, 4 là dãy s1.5, 2, 3. Như vy các s ca dãy trung bình có th là phâns. Tuy nhiên, bài toán này ch xét dãy trung bình là mtdãy s nguyên.

Cho dãy s không gim n phn t  m1, . . . ,mn. Hãytìm s dãy s nguyên không gim gm n + 1 phn t s1, . . . , sn+1 có dãy trung bình là dãy m1, . . . ,mn.

Nhim v: Vit chương trình:

- Đc d liu t input chun dãy s nguyên không gim n phn t. - Tìm s các dãy s nguyên không gimn + 1 phn t có dãy trung bình là dãy n phn t trên.

- Vit kt qu tìm đưc ra output chun.

Đnh dng tp vào: Dòng đu tiên ca input chun chas nguyên n (2 ≤ n ≤ 5000000). n dòng tip theo cha n

s nguyên ca dãy s m1, . . . ,mn. Dòng th i + 1 cha snguyên mi (0 ≤ mi ≤ 1000000000). Bn có th làm vi50% test mà n ≤ 1000 và 0 ≤ mi ≤ 20000.

Đnh dng tp ra: Chương trình ca bn phi ghi ra out- put chun mt s nguyên duy nht là s dãy s nguyênkhông gim nhn dãy s đã cho là dãy trung bình.

Ví d.

D liu vào kt qu đúng3

25

9

4

Tht vy, có 4 dãy s nhn dãy 2, 5, 9 là dãy s trung bìnhđó là:

+ 2, 2, 8, 10,

+ 1, 3, 7, 11,

+ 0, 4, 6, 12,

+ -1, 5, 5, 13.

Li gii 2.2. Phân tích. Gi min[i] và max[i] là

min giá tr ca s S[i] đ tha mãn dãy m[1] đn

m[i − 1]. Ta có m[i − 1] ≤ min[i] ≤ max[i] ≤ m[i]

vi i > 1. (min giá tr bao gm c 2 đu mút) Ta khito min[1]=−∞ , max[1] = m[1].

Khi đã bit min[i − 1],max[i − 1] ta s tínhđưc min[i],max [i] bng cách ly đi xng đonmin[i − 1],max[i − 1] qua m[i − 1], ri ly giao cađon min[i],max[i] vi đon [m[i], +∞). Nu min giátr ca S[i] là rng thì kt lun luôn đáp s bng 0.Cui cùng đáp s s là max[n + 1]−min[n + 1] + 1.

Tuy nhiên vn đ là chúng ta không làm đưcmng 5 000 000 phn t longint. Chúng ta cóth nhn thy, min[i],max[i] đu đưc tính tmin[i − 1],max[i − 1] nên chúng ta có th dùng các

 bin đơn luân phiên nhau. Như vy đ phc tp là

O(n) b nh O(1). Dưi đây là chương trình minhha:

Phương án cài đt

Chương trình 2: mean.pas

1 const2 maxN = 5000005;3 INF = 1111111111;4 var n, res : longint ;5 procedure process;6 var i : longint ;

7 t , bi, bi1, mini, maxi, mini1, maxi1: int64 ;8 x: extended;9 begin

10 res := maxlongint;11 readln(n);12 readln(x);13 bi1 := trunc(x ∗ 2);14 mini1 := −INF;15 maxi1 := bi1 shr 1;16 for i := 2 to n do17 begin18 readln(x);

19 bi := trunc(x ∗ 2);20 mini := bi1 − maxi1;21 maxi := bi1 − mini1;22 if  2 ∗ mini − bi > 0 then23 begin24 writeln(’0’) ;25 exit ;26 end;27 t := bi shr 1;28 if  maxi > t then maxi := t;29 maxi1 := maxi;30 mini1 := mini;31 bi1 := bi;32 end;33 res = maxi − mini + 1;34 writeln(res);35 end;

Nguyn Hu Đin 4/15 http://nhdien.wordpress.com

Page 5: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 5/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

37 begin38 process ;39 end.

Bài 2.3 (Hành trình qua núi )

File ngun mou.*B nh cho phép: 256MB. Thi gian chy ti đa: 3s.

Công viên gii trí Liên Sơn mi m mt đưng đi đcbit vưt qua các ngn núi. Con đưng này bao gm nđon ni lin nhau, đon đu tiên, luôn xut phát t t đcao 0. Byteman là ngưi điu khin, ông có th điu chnhcác đon - vic điu chnh là thay đi đ cao các đu mútca các đon liên tip nhau. Mi ln điu chnh mt đonthì các đon theo sau s đưc nâng lên hoc h xung đ n

đon luôn ni vi nhau và duy trì đon đu tiên luôn xut phát t đ cao là 0. Hình bên dưi mô t hai ví d v cáchđiu chnh này.

 Mi ln bt đu mt hành trình, các ôtô đưc np nănglưng đ đi ti đ cao h. Điu đó có nghĩa là ôtô có th tiptc hành trình min là đ cao ca đon hin ti không vưtquá h.

Cho trưc lch các hành trình và các ln điu chnh xenk trong ngày, vi mi hành trình hãy tính s chng mà

mi ôtô đi đưc trưc khi nó dng li.Trong bng đó, mi chng đưc biu din bng mt dãy

n s thay đi đ cao. S th itrong dãy - di th hin s thayđi đ cao (centimét) ti đon th i. Gi s sau khi đi quai− 1 đon ôtô đn đ cao h centimét, sau khi đi qua i đon,ôtô s đt đn đ cao h + di centimét.

Ban đu các đon đu nm ngang, nghĩa là di = 0 vimi i. Các lưt hành trình và s điu chnh trên hành trìnhđan xen nhau trong c ngày hot đng. Mi ln điu chnh

đưc xác đnh bng 3 s: a, b và D. Các đon đưc chnht a đn b. Đ cao đưc chnh trong các đon này là D.Nghĩa là di = D vi mi a ≤ i ≤ b. Mi hành trình đưcxác đnh bi mt s h - đ cao ln nht mà ôtô có th đnđưc.

Nhim v: Vit chương trình:

- Đc d liu t input chun dãy các hành trình và cácln điu chnh.

- Vi mi hành trình hãy tính s đon mà ôtô đi đưc.

- Vit kt qu ra output chun.

Đnh dng tp vào: Dòng đu tiên cha s nguyên dương

n - s đon trên con đưng, 1 ≤ n ≤ 1000000000. Các

dòng tip theo bao gm các ln điu chnh xen k vi hànhtrình, sau đó là ký hiu kt thúc. Mi dòng có th là:

- S điu chnh - mt ký t ‘I’ và cács nguyên a, b,D cách nhau bi mt du trng(1 ≤ a ≤ b ≤ n,−1000000000 ≤ D ≤ 1000000000).

- Mt hành trình - mt ký t ‘Q’ và s nguyênh(0 ≤ h ≤ 1000000000) cách nhau bi mt du trng.

- Ký hiu kt thúc - ký t ‘E’.

Bt kỳ lúc nào đ cao nào cũng luôn nm trong khong[0, 1000000000] centimét. D liu vào cha không quá 100000 dòng. Có 50% test n tho mãn 1 ≤ n ≤ 20000 và d liu vào cha không quá 1000 dòng. D liu ra: Dòng th i ca output cha mt s nguyên là s đon mà xe du điđưc trong hành trình th i.

Ví d.

D liu vào Kt qu đúng4

Q 1

I 1 4 2Q 3

Q 1

I 2 2 - 1

Q 3

E

4

1

03

 Hình 2: vd

Nguyn Hu Đin 5/15 http://nhdien.wordpress.com

Page 6: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 6/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

Li gii 2.3. Phân tích. Đây là bài toán thiên v

cu trúc d liu, c th là interval tree. Mi nút trêncây s lưu thông tin v mt đon đưng ray liên tip.Vi nút P lưu thông tin v đon [L,R], nút P s lưuSP là chênh lch gia đim R và L. HP là đ cao ln

nht trong đon [L,R]. Nu tính gc là đim L.

S p = ∑ L≤i≤R

di

 H  p = max( ∑ L≤i≤R

di vi T nm trong [L, R])

Nút P s là lá nu mi di đu bng nhau.Nu trưng hp nút P không phi là lá, thì

P s có 2 nút con là P1 và P2. P1 lưu thôngtin v đon [L, (L + R) ÷ 2], P2 lưu thôngtin v đon [(L + R) ÷ 2 + 1,R]. Ta s cóSP = SP1 + SP2;HP = max( HP1, SP1 + HP2). Nugi M là s yêu cu, cách làm này có đ phc tp làO( M ∗ logN ), tuy nhiên b nh lên đn O(N ∗ logN ).Vì gii hn N  là 1 t, ta s không th lưu đưc. Ta sphi tìm cách khác đ lưu. Ta đ ý thy, M ≤ 100000.Như vy, s có không quá 200 000 đu mút các đon

ray. Ta ch cn sa đi mt chút, nút P lưu đon t Lđn R đưc sa li thành đon t đu mút th L đnđu mút th R. Dưi đây là chương trình mu cho

 bài này. Đây là chương trình vit bng C++ ca MaxZhou (thí sinh Trung Quc trong cuc thi IOI online)

Phương án cài đt

Chương trình 3: mou.c

1 #include2 #include

3 #include4 #define INFINITY 1000000000

6 struct Titem {7 int oper;8 int L, R, v;9 };

11 struct Tnode {12 int L, R;13 int fm, sum, v;14 bool used;15 int Lch, Rch;16 };

18 void init ();19 void prefix () ;

20 void solve ();21 void createtree ( int r , int L, int R);22 void inserttree ( int r , int L, int R, int v) ;23 int findtree ( int r , int limit ) ;24 inline int count(int r) ;

26 int n;

28 int nitem;29 Titem item[110000];

31 int nlist , list [210000];

33 int nnode;34 Tnode tree[410000];

36 int main() {37 init ();38 prefix ();

39 solve ();40 return 0;41 }

43 void init () {44 char line [1000];45 int L, R, v;

47 scanf(’%d’, &n);48 while ( scanf(’%s’, line )==1 )49 if  ( strcmp( line , ’ I ’)==0 ) {50 scanf(’%d%d%d’, &L, &R, &v);

51 item[nitem].oper=0; item[nitem].L=L;52 item[nitem].R=R; item[nitem].v=v;53 ++nitem;54 }55 else if  ( strcmp( line , ’Q’)==0 ) {56 scanf(’%d’, &v);

58 item[nitem].oper=1; item[nitem].v=v;59 ++nitem;60 }61 else break;62 }

64 void prefix () {65 int i ;

67 for ( i=0; i68 if  ( item[ i ]. oper==0 ) {69 list [ nlist ++]=item[i].L;70 list [ nlist ++]=item[i].R+1;71 }72 list [ nlist ++]=1; list[ nlist ++]=n+1;

74 std :: sort ( list , list +nlist );75 nlist =std::unique( list , list +nlist)− list ;

77 for ( i=0; i78 if  ( item[ i ]. oper==0 ) {79 item[ i ]. L=std::lower_bound(list,

Nguyn Hu Đin 6/15 http://nhdien.wordpress.com

Page 7: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 7/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

80 list +nlist, item[i ].L)− list;81 item[ i ]. R=std::lower_bound(list,82 list +nlist , item[ i ]. R+1)−list−1;83 }84 }

86 void solve () {87 int i ;

89 tree [nnode].fm=−INFINITY; ++nnode;90 createtree (1, 0, nlist −2);91 for ( i=0; i92 if  ( item[i ].oper==0 )93 inserttree (1, item[ i ]. L, item[ i ]. R, item[ i ]. v);94 else {95 int res = findtree (1, item[ i ]. v);

97 printf (’%dn’, res);98 }

99 }

101 void createtree ( int r , int L, int R) {102 tree [ r ]. L=L; tree[ r ]. R=R;103 tree [ r ]. fm=tree[r]. sum=0; tree[r ]. used=false;104 tree [ r ]. Lch=tree[r ]. Rch=0;

106 if  ( L107 tree [ r ]. Lch=++nnode;108 createtree (nnode, L, (L+R)/2);109 tree [ r ]. Rch=++nnode;110 createtree (nnode, (L+R)/2+1, R);

111 }112 }

114 void update(int r) {115 if  ( tree[ r ].used ) {116 tree [ r ]. sum=count(r)∗tree[r].v;117 tree [ r ]. fm=std::max(tree[r ]. v, tree [ r ]. sum);118 }119 else {120 int Lch = tree[r ]. Lch, Rch = tree[r ].Rch;

122 tree [ r ]. sum=tree[Lch].sum+tree[Rch].sum;123 tree [ r ]. fm=std::max(tree[Lch].fm,

124 tree [Lch ].sum+tree[Rch].fm);125 }126 }

128 void inserttree ( int r , int L, int R, int v) {129 if  ( L<=tree[r].L && R>=tree[r].R ) {

130 tree [ r ].used=true; tree[ r ]. v=v; update(r);131 return;132 }

134 int Lch = tree[r ]. Lch, Rch = tree[r ]. Rch;135 if  ( tree[ r ].used && tree[r ].L136 tree [Lch]. used=true; tree[Lch].v=tree[r ]. v;137 update(Lch);138 tree [Rch].used=true; tree[ Rch].v=tree[r ]. v;139 update(Rch);140 }141 tree [ r ].used=false;

143 if  ( L<=(tree[r].L+tree[r ]. R)/2 )144 inserttree (Lch, L, R, v);145 if  ( R>(tree[r ]. L+tree[r ]. R)/2 )146 inserttree (Rch, L, R, v);147 update(r);148 }

150 int findtree ( int r , int limit ) {151 if  ( tree[ r ].used || tree[ r ].L==tree[r].R )152 if  ( tree[r ].v<=0 ) return count(r);153 else return std :: min(limit/ tree[ r ]. v, count(r));

155 int Lch = tree[r ]. Lch, Rch = tree[r ]. Rch;156 if  ( tree [ tree [ r ]. Lch].fm<=limit )157 return count(Lch)+findtree(Rch, limit−tree[Lch].sum);158 else159 return findtree (Lch, limit );160 }

162 inline int count(int r) {163 int L = tree[r ]. L, R = tree[r ]. R;164 return list [R+1]−list[L];165 }

Bài 2.4 (Ngày sinh nht)File ngun bir.*B nh cho phép: 32MB. Thi gian chy ti đa: 2s.

 Hôm nay là sinh nht ca Byteman. Có n ngưi bn(k c Byteman) tham d ba tic. Các bn đưc đánh sth t t 1 đn n. B m Byteman chun b sn mt chicbàn tròn ln và đt n chic gh xung quanh cái bàn đ các

bn đn d tic ngi. Bn s 1 ngi vào mt chic gh nàođó, sau đó bn s 2 ngi vào chic gh k bên trái bn s 1.Bn s 3 ngi vào chic gh k bên trái na và c như th.

Cui cùng, bn s n s ngi vào chic gh trng cui cùng,tc là ngi gia bn s 1 và n− 1.

B m ca Byteman rt hiu lũ bn ca Byteman, hbit có mt s đa tr rt nghch ngm nu chúng ngi gnnhau, do đó h đã nghĩ ra cách là đi ch nhng đa trnày đi. Mt cách xp th t gh ngi có th đưc biu dinbng mt hoán v p1, p2, . . . , pn ( p1, p2, . . . , pn là các s

nguyên phân bit trong khong t 1 đn n), bn s p1 s ngi gia pn và p2, bn pi (vi i = 2 ,3 , . . . , n− 1) s ngi gia bn pi−1 và pi+1, bn pn ngi gia bn pn−1 và bn

Nguyn Hu Đin 7/15 http://nhdien.wordpress.com

Page 8: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 8/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

 p1. Chú ý rng bn p1 có th ngi bên trái hoc bên phibn pn.

Đ sp xp tt c các bn vào v trí ch đnh, b mByteman phi di chuyn mi đa tr xung quanh cái bànsang trái hoc sang phi mt s ch ngi. Vi mi đa tr

h phi xác đnh xem s di chuyn theo hưng nào (trái hay phi) và khong cách di chuyn (qua bao nhiêu ch ngi).Sau khi đưc lnh ca h, tt c nhng đa tr cùng đnglên, di chuyn đn chic gh ca mình và ngi xung. Vicđi ch s làm cho ba tic tr nên hn lon. Mc đ hnlon đo bng khong cách ln nht trong các ln di chuynch ngi ca lũ tr. V trí ngi có th đưc sp xp theonhiu cách, b m ca Byteman mun tìm mt cách có mcđ hn lon nh nht. Bn hãy giúp h tìm ra mt cách như 

vy đ sp xp ba tic.Nhim v

Vit chương trình:

• Đc t input chun gm s bn và hoán v mô t th t các v trí cn đt đưc.

• Tìm mc đ hn lon nh nht.• Vit kt qu ra output chun.

Đnh dng tp vào: Dòng đu tiên cha s nguyêndương n (1 ≤ n ≤ 1000000). Dòng th hai cha n snguyên p1, p2, . . . , pn cách nhau bi các khong trng. Cács p1, p2, . . . , pn s to thành mt hoán v ca tp hp{1 ,2 , . . . , n} mô t th t các v trí cn đt đưc. Có 50%test mà n không vưt quá 1000.

Đnh dng tp ra: Dòng đu tiên và duy nht ca outputchun cha s nguyên là mc đ hn lon nh nht.

Ví d.

bir.inp Kt qu đúng6

3 4 5 1 2 6

2

 Hình 3:

 Hình bên trái là th t ban đu ca các bn mi đn d ba tic. Hình gia là kt qu ca vic di chuyn: bn s1 và 2 di chuyn sang 1 gh, bn s 3 và 5 di chuyn sang

2 gh, bn s 4 và 6 không di chuyn. Điu kin sp xpđã đưc đáp ng: 3 ngi gia 6 và 4, 4 ngi gia 3 và 5,5 ngi gia 4 và 1, 1 ngi gia 5 và 2, 2 ngi gia 1 và6, 6 ngi gia 2 và 3. Có mt cách đi ch khác tho mãnnhư hình bên phi. Trong c hai cách không có bn nào di

chuyn quá 2 ch ngi

Li gii 2.4. Phân tích. Đ bài yêu cu sp xp

li ch ngi ca nhng đa tr sao cho khong cáchmà đa tr phi di chuyn xa nht là ngn nht cóth đưc. Chúng ta nên lưu ý có 2 cách sp xp cuicùng: thun chiu kim đng h và ngưc chiu kimđng h. Ta có nhn xét là hai trưng hp này đưcgii quyt như nhau, nên ta ch gii quyt trưng hp

thun chiu kim đng h:Gi a[i] làvtríbanđucanhngđatr.Chúng

ta chuyn đa tr th i đn v trí i. Đt d[i] là mts th hin hưng và khong cách đa tr i phi dichuyn.

• |d[i]| = khong cách di chuyn ca đa tr thi.

• d[i] > 0 nu di chuyn cùng chiu kim đng h.• d[i] < 0 nu di chuyn ngưc chiu kim đng

h.• Nu khong cách d[i] bng N/2 (N chn) thì ưu

tiên di chuyn thun chiu kim đng h.

Ta có: −((N − 1)÷ 2) ≤ d[i] ≤ N ÷ 2

Nu mi đa tr đưc dch sang phi mt đơn v,thì d[i] s thay đi theo

• Nu d[i] ≤ N ÷ 2 thì d[i] = d[i] + 1.• Nu d[i] = N ÷ 2 thì d[i] = −((N − 1)÷ 2)

Nhim v ca chúng ta là xoay cách đa tr thêmmt s ln đ sao cho max(|d[i]|) là min. Chúng tanhn thy có th tính đưc giá tr này trong thigian O(n). Xét C là đon liên tip dài nht thuc[−((N − 1) ÷ 2), N ÷ 2] mà không có d[i] nào xuthin. Chú ý đon dài nht có th là [a,N ÷ 2] hp[−((N − 1)÷ 2), b] vi b < a. Nu C có P phn t thìđáp s s là (N − P)÷ 2.

Dưi đây là bài gii đã đưc 100 đim.

Phương án cài đt

Chương trình 4: bir.c

1 #include

Nguyn Hu Đin 8/15 http://nhdien.wordpress.com

Page 9: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 9/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

2 #include3 #include4 #define MAXN 10000015 #define Swap(x, y) ((x) ^= (y), (y) ^= (x), (x) ^= (y))6 int a[MAXN], N, i, j;7 int u[MAXN];

9 void Reverse(void)10 { int i ;11 for (i = 0; i <= (N − 2) / 2; i ++)12 Swap(a[i ], a[N − i − 1]);13 }14 int GoodMin(void)15 { int i , j , first , last , max_gap = 0;16 memset(u, 0, sizeof (u));17 for (i = 0; i < N; i ++)18 { j = a[ i ] − i;19 while (j < 0) j += N;20 u[j] = 1;

21 }22 for (i = 0; u[i] == 0; i ++);23 first = last = i;24 for (++ i; i < N; i ++)25 if  (u[i ])26 {27 if  ( i − last > max_gap) max_gap = i − last;28 last = i;29 }

30 if  (N − last + first > max_gap)31 max_gap = N − last + first;32 return (N − max_gap + 1) / 2;33 }

35 void GoodSolve(void)

36 {37 int Ans1, Ans2;38 Ans1 = GoodMin();39 Reverse();40 Ans2 = GoodMin();41 printf ("%dn", Ans1 < Ans2? Ans1 : Ans2);42 }

44 int main(void)45 {46 // freopen("bir .in", "r", stdin);47 scanf("%d", &N);48 for (i = 0; i < N; i ++)

49 {50 scanf("%d", &(a[i]));51 −− a[i];52 }53 GoodSolve();54 return 0;55 }

Bài 2.5 (Trò chơi ct hình ch nht)

File ngun rec.*B nh cho phép: 32MB. Thi gian chy ti đa: 14s*.

Chúng ta có mt trò chơi dành cho hai ngưi như sau:Cho trưc mt hình ch nht kích thưc x× y (x, y là cács nguyên dương). Hai ngưi chơi thay phiên nhau đi. Miln đi đó là mt nhát ct dc hoc ngang chia hình ch nhtthành 2 hình ch nht khác. Kích thưc các chiu ca cáchình ch nht thu đưc phi là s nguyên.

Sau khi ct, hình ch nht bé hơn (din tích bé hơn)

s đưc b đi và hình ch nht còn li s đưc chuyn chongưi chơi kia. Nu 2 hình ch nht đưc ct ra có dintích bng nhau thì b qua hình nào cùng đưc. Ngưi chơinào nhn đưc hình ch nht 1 1 thì không th ct tipđưc, và là ngưi thua cuc trong trò chơi.

Nhim v ca bn là vit mt chương trình đ chơivà thng trò chơi này. Chương trình phi s dng mtthư vin đc bit đ chơi. Thư vin cung cp các hàmdemension_x() và demensiony() đ tr v kích thưc ca

hình ch nht. Khi đu kích thưc ca hình ch nhttrong khong t 1 đn 100 000 000 và ít nht có mt chiuln hơn 1. Trong 50% test kích thưc không quá 25.

 Hình 4: Các cách ct hình ch nht 4× 3

Còn có th tc cut(huong, vitri), th tc này đưcchương trình ca bn gi khi thc hin mt nưc đi. Cáctham s huong và vitri mô t hưng và v trí ca nhát cttương ng. Tham s huong có th nhn các giá tr verti-cal hoc horizontal. Nu huong = vertical thì nhát ct làmt đưng thng đng và tham s vitri th hin hoànhđ ca nhát ct (xem hình bên) và bn phi đm bo rng1 ≤ vitri ≤ demension_x() − 1. Nu huong = horizon-tal thì nhát ct là mt đưng thng nm ngang và thams vitri th hin tung đ ca nhát ct và bn phi đm bo

rng 1 ≤ vitri ≤ demension_ y() − 1.

Khi chương trình ca bn bt đu, nó s tr thành mtngưi chơi trong trò chơi. Chương trình ca bn đi trưc -

Nguyn Hu Đin 9/15 http://nhdien.wordpress.com

Page 10: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 10/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

nó phi ct hình ch nht ban đu. Khi chương trình cabn gi th tc cut, nưc đi đó đưc ghi li và chuyn lưtđi cho đi th ca chương trình. Sau nưc đi ca đi th,lưt đi li thuc v chương trình ca bn. Giá tr tr v cadimension_x() và dimension_ y() s cp nht theo tình

trng sau mi nưc đi. Khi chương trình ca bn thng,thua hoc đi sai (ví d gi th tc cut vi tham s khônghp l) cuc chơi s b dng li ngay. Vic kt thúc chươngtrình là mt quá trình t đng, do đó chương trình cabn phi c đi đưc càng nhiu nưc càng tt. Bn đưcbit thêm rng vi mi test d liu, luôn tn ti mt chinlưc mà chương trình ca bn s thng.

Chương trình ca bn không đưc phép đc hay vitvào bt kì tp nào, nó không đưc s dng input/output

chun và không đưc thay đi vùng b nh không thucchương trình. Vi phm bt kỳ điu l nào, kt qu ca bncó th b loi.

Th nghim

Đ bn có th th nghim thư vin, bn s đưc cungcp mt s ví d ca các đu th trong thư vin: mã ngunca chúng các file preclib.pas, creclib.c và creclib.h. Thư vin có th download ti http://contest/. Chin lưc cachúng rt đơn gin, khi chương trình ca bn thc hin,

nó s đu vi nhng đi th đơn gin này. Bn có th t do chnh sa chúng và th cho chương trình ca bn đuvi nhng đi th mnh hơn. Tuy nhiên sau này chươngtrình ca bn s phi đu vi mt đi th khác mnh hơnnhiu.

Khi bn hoàn thành chương trình vi vic s dng giaodin TEST, nó s đưc biên dch vi thư vin ca mt đith không chnh sa đưc. File input s đưc đưa vào inputchun trong chương trình ca bn. File input phi có hai

dòng, mi dòng cha mt s nguyên. Dòng đu cha chiurng và dòng th hai cha chiu cao ca hình ch nht banđu. Các kích thưc này cũng đưc đi th trong thư vinđc.

Nu bn chnh sa phn thc hin (implementation)ca thư vin preclib.pas, hãy biên dch li nó bng lnh: ppc386 -O2 preclib.pas. Cú lnh này s sinh ra các file pre-clib.o và preclib.ppu. Các file này đưc dùng đn khi biêndch chương trình ca bn, và phi đt thư mc cha

chương trình ca bn. Bn không đưc chnh sa phn giao din (interface) ca thư vin preclib.pas.

Nu bn chnh sa thư vin creclib.c, bn phi nh đt

nó (đi cùng vi creclib.h) vào thư mc cha chương trìnhca bn - chúng cn đ biên dch. Bn không đưc chnhsa creclib.h.

Bn đưc cung cp thêm hai chương trình đơn ginminh ho vic s dng các thư vin trên: crec.c và crec.pas.

(Nh rng đó không phi là li gii chính xác). Bn có th biên dch chúng bng các lnh:

gcc -O2 -static crec.c creclib.c -lm

g++ -O2 -static crec.c creclib.c -lm

ppc386 -O2 -XS prec.pas

Thư vin

Bn đưc cung cp mt thư vin vi các chc năng:

• Thư vin

Free Pascal (preclib.ppu, preclib.o)

1 type direction = ( vertical , horizontal ) ;2 function dimension\_{}x(): longint;3 function dimension\_{}y(): longint;4 procedure cut(dir: direction ; position : longint ) ;

Thêm dòng lnh sau vào file file ngun rec.pas cabn:Uses preclib;

Đ biên dch chương trình ca bn, copy cácfile preclib.o và preclib.ppu vào thư mccha file ngun ca bn và thc hin lnh:ppc386 -O2 -XS rec.pas

File prec.pas cho bn mt ví d v cách s dngthư vin preclib.

• Thư vin GNU C/C++ (creclib.h, creclib.c)

1 typedef enum _direction direction ;2 { vertical , horizontal }3 int dimension\_{}x();4 int dimension\_{}y();5 void cut( direction dir , int position );

Thêm dòng lnh sau vào file ngun rec.c hoc rec.cppca bn:#include ”creclib.h”

Đ biên dch chương trình ca bn, copy file preclib.cvà preclib.h vào thư mc cha file ngun ca bn vàthc hin lnh:gcc -O2 -static rec.c creclib.c -lm

hoc:g++ -O2 -static rec.cpp creclib.c -lm

File crec.c cho bn mt ví d v cách s dng thư vin trong C.

 Mt tương tác ví d

Nguyn Hu Đin 10/15 http://nhdien.wordpress.com

Page 11: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 11/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

Dưi đây là mt ví d v s tương tác gia chươngtrình ca bn và thư vin ca giám kho, th hin mt quátrình chơi đơn gin. Cuc chơi bt đu vi hình ch nht4 x 3. Tn ti chin lưc đ chương trình ca bn chinthng.

Chương trìnhca bn gi

 Hiu ng

dimension_x Tr v giá tr 4dimension_y Tr v giá tr 3cut(vertical, 1)y Nhát ct ca bn đưc ghi li và

chuyn hình ch nht 3x3 chođi th. Đi th ct đ còn lihình ch nht 3x2 chuyn chobn

dimension_x Tr v giá tr 3dimension_y Tr v giá tr 2cut(vertical, 1)y Nhát ct ca bn đưc ghi li và

chuyn hình ch nht 3x1 chođi th. Đi th ct đ còn lihình ch nht 3x1 chuyn chobn

dimension_x Tr v giá tr 2dimension_y Tr v giá tr 1cut(vertical, 1)y Nhát ct ca bn đ li hình

ch nht 1x1 vì vy bn thng,chương trình t đng kt thúc.

* Thi gian thc hin trong thư vin là không quá 4s.

Li gii 2.5. Phân tích. Ta có mt vài đnh nghĩa

sau:

• Mt trng thái ca bng đưc th hin bng cps (n, m).

• Mt trng thái P đưc gi là trng thái thngnu ta luôn có cách thng mc cho bưc tip

theo đi th đi th nào.• Mt trng thái P đưc gi là trng thái thua nu

đi th luôn có cách thng mc cho các bưctip theo ta đi th nào.

Theo đnh nghĩa trên:

• (1, 1) là trng thái thua.• Mt trng thái thng nu có tn ti ít nht mt

nưc đi dn đn trng thái thua.• Mt trng thái thua mi nưc đi tip theo đu

hưng đn mt trng thái thng.

Chúng ta có th lp mt bng như sau, v trí i j là du* thì trng thái (i, j) là trng thái thua và ngưc li.

Hình 5:

Sau khi phân tích, chúng ta có th rút ra mt nhnxét như sau: Trng thái (n,m) là trng thái thua khi vàch khi (m + 1) = 2k(n + 1). Ta s chng minh nhnxét này:

Trưng hp k = 0←→ m = n.

• m = n = 1: (m, n) là trng thái thua theo đnh

nghĩa.• m > 1: Nu đi th đưa ta vào trng thái (n, p)

thì m/2 ≤ p < m. Vy ta có th đi t trng thái(n, p) đn trng thái ( p, p) mt trng thái thua.

Trưng hp k = 0. Không mt tính tng quát gis k > 0. Vì

(m + 1) = 2k(n + 1) ←→ (n + 1) = 2−k(m + 1)

Khi đang trng thái (n,m) ta s có hai hưng: ( p,m)

hoc (n, q):• Nu sau khi ct, ta đn trng thái

( p,m). Ta có n/2 ≤ p < n. Màn = 2k(m + 1) − 1 nên ta có bt đng thcsau: 2k−1(m + 1) − 1 < p < 2k(m + 1) − 1.Như vy, ngưi tip theo có th thc hinnưc đi t trng thái ( p,m) đn trng thái(2k−1(m + 1)− 1,m).

• Nu sau khi ct, ta đn trng thái (n, q) trongđó m/2 ≤ q < m. Ta s chng minh không tnti s nguyên tha mãn n = 2i(q + 1)− 1. Ta schng minh bng phn chng. Gi s tn ti snguyên i tha mãn đng thc n = 2i(q + 1)− 1.

Nguyn Hu Đin 11/15 http://nhdien.wordpress.com

Page 12: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 12/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

- Ta có n = 2k(m + 1)− 1vm > q nên i > k.

- Mt khác, m/2 ≤ q, ta có:

- 2k(m +1)−1 = n = 2i(q +1)−1 ≥ 2i(m/2+1)−1

= 2i−1(m + 2) > 2i−1(m + 1)− 1

- ←→ k > i− 1↔ i < k + 1i là s nguyên và k < i < k + 1 (vô lý).

Vì vy, nu m + 1 = 2k(n + 1) thì trng thái này làtrng thái thua. Nhim v ca chúng ta trong mi lnthc hin mt nưc đi t (n,m) đn (n,m) sao chom + 1 = 2i(n + 1). Không mt tính tng quát, ta gis n ≥ m. Ta s có chn m, n sao cho:

• m = m

• n = 2k(m + 1)− 1, ln nht và nh hơn n.

Đ phc tp ca thut toán trong trưng hp xunht là O(nlogn)

Phương án cài đt

Chương trình 5: rec.pas

1 uses preclib ;2 var3 x, y, m: longint ;4 a: array [1..100] of  longint ;

6 procedure make(u, v: longint);7 begin8 if  odd(v) then9 v := v div 2 + 1

10 else11 v := v div 2;12 m := 1;13 a[1] := u;14 while a[m] < v do15 begin

16 inc(m);17 a[m] := a[m − 1] ∗ 2 + 1;18 end;19 end;

21 begin22 while true do23 begin24 x := dimension_x;25 y := dimension_y;26 if  (x > y) and (2 ∗ y >= x) then27 begin28 cut( vertical , y);

29 continue;30 end;31 if  (y > x) and (2 ∗ x >= y) then32 begin33 cut( horizontal , x);34 continue;35 end;36 if  x > y then make(y, x) else make(x, y);37 if  x > y then38 cut( vertical , a[m])39 else40 cut( horizontal , a[ m]);

41 end;42 end.

Bài 2.6 (Các dòng sông)File ngun riv.*B nh cho phép: 32MB. Thi gian chy ti đa: 1s.

C vương quc Byteland gn như đưc bao bc binhng cánh rng và nhng dòng sông. Các dòng sông nh

 gp nhau to nên mt dòng sông ln hơn, các dòng sôngln li có th gp nhau na, c th cui cùng các sông đuđ ra mt dòng sông ln. Dòng sông ln đ ra bin cnhth trn Bytetown.

Byteland có n ngôi làng gn sông. Hin ti, có mtxưng máy cưa ln Bytetown tt c cây g đưc chttrong vương quc. Cây g đưc th trôi t các làng xungsông đ v xưng cưa Bytetown. Quc vương Bytelandquyt đnh xây thêm k xưng cưa đ gim chi phí vn

chuyn các cây cây g trên sông như vy. Sau khi xây dngcác xưng cưa, các cây g không cn phi th trôi v Byte-town na mà có th đưc x lí ngay xưng cưa đu tiên

 gp trên đưng trôi. Đương nhiên là các cây g đưc cht làng có xưng cưa thì không cn chuyn đi đâu c. Chú ýrng các sông Byteland không phân nhánh. Vì th t milàng ch có mt đưng sông duy nht đ đi đn Bytetown.

Quc vương nm đưc s cây ca các làng cht đưc

mi năm. Bn phi xác đnh nơi xây các xưng cưa đ tithiu tng chi phí vn chuyn cây mi năm. Phí vn chuyntrên sông là 1 xu trên 1 kilômét cho mt cây.

 Nhim v

Vit chương trình:

• Đc t input chun s làng, s xưng cưa đưc xâythêm, s cây ca mi làng cht đưc trong mt nămvà mô t v các dòng sông.

• Tính tng chi phí vn chuyn nh nht bng đưng

sông sau khi đã xây thêm các xưng cưa.• Vit kt qu ra output chun.

Đnh dng tp vào: Dòng đu tiên cha hai s nguyên:

Nguyn Hu Đin 12/15 http://nhdien.wordpress.com

Page 13: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 13/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

n - s ngôi làng không k Bytetown (2 ≤ n ≤ 100), và k

- s xưng cưa đưc xây thêm (1 ≤ k ≤ 50vk ≤ n). Cácngôi làng đưc đánh s 1 ,2 , . . . , n, trong khi đó Bytetownđưc đánh s 0. Mi dòng trong s n dòng tip theo cha 3s nguyên, cách nhau bi du trng. Dòng th i + 1 cha:

• wi - s cây cht đưc làng i mi năm(0 ≤ wi ≤ 10000),

• vi - làng đu tiên (hoc Bytetown) gp khi đi t làngi

• di - khong cách (kilômét) t làng i đn làng vi

(1 ≤ di ≤ 10000)

Tng chi phí vn chuyn cây v xưng cưa Bytetownmi năm không quá 2 000 000 000 xu.

Trong 50% test, n không vưt quá 20.

Đnh dng tp ra: Dòng đu tiên và duy nht cha snguyên duy nht là tng chi phí vn chuyn bng đưngsông nh nht (tính bng xu).

Ví d.

riv.inp riv.out4 2

1 0 1

1 1 1 0

1 0 2 5

1 2 3

4

 Hình 6:

 Hình v trên th hin d liu vào. S th t các làng làs ghi trong vòng tròn. S ghi dưi vòng tròn th hin scây cht đưc trong mt năm làng đó. S trên các đưngmũi tên th hin chiu dài đưng sông.

Các xưng cưa cn đưc xây dng làng s 2 và 3.

Li gii 2.6. Phân tích. Đây là mt bài toán quy

hoch đng trên cây khá hay. Trưc tiên, chúng tacn xây dng mt cây mà mi nút trên cây, ch códuy nht mt đưng đn gc (Byteland town). v là

cha ca u nu v là ngôi làng đu tiên trên đưng đit u đn gc.

Gi r là gc ca cây (Byteland town). Đt depth(u)

là s cnh trên đưng đi t u đn r. Ta có th tínhđưc depth(u) trong O(n). Đt deg(u) là s con ca u

và s cây g b ct nút u là trees(u).

Hàm quy hoch đng A[v, t, p] vi ý nghĩa chi phíít nht ca vic xây t nhà máy trong cây con có gc làv và nhng cây g mà không đưc x lý trong câycon v,thìstrôiđnnút p (pnmtrênđưngt v đnr). Chúng ta s tính A[v, t, p] vi mi v và 0 ≤ t ≤ k.Ta s tính đưc A[v, t, p] theo công thc sau:

• 0 nu cây con gc v có đúng t nút• min( A1[v, t, p], A2[v, t]) trong trưng hp còn

li

trong đó

• A1[v, t, p] là chi phí ít nht ca vic xây dng tnhà máy trong cây con có gc là v, không xâynhà máy ti nút v và nhng cây g mà khôngđưc x lý trong cây con v, thì s trôi đn nút p ( p nm trên đưng t v đn r).

• A2[v, t] làchiphíítnhtcavicxâydngtnhà

máytrongcâyconcógclàvvàtivcóxâymtnhà máy.

Gi d = deg(v) và vi là các con ca v. Ta s tính A1[v, t, p] và A2[v, t] theo công thc sau:

• A1[v, t, p] = trees(v)∗ khong cách(v, p)+

min(∑ i = 1..dA[vi, ti, p]) tha mãn ∑ ti = t.• A2[v, t] = min(∑ i = 1..dA[vi, ti, depth(v)])

tha mãn ∑ ti = t− 1.

Nhìn vào 2 công thc trên, ta s thy ngay rng,chúng ta cn phi xét mi cách chia t nhà máy vàocác cây con ca v. Trong trưng hp nút v có nhiunút con, chúng ta cn phi có mt thut toán tt hơnlà duyt. Chúng ta s cn đn mt hàm quy hochđng tip theo:

• B[i, s, v, p] là chi phí ít nht đ xây s nhà máytrong i cây con gc v1, v2, v3, . . . , vi ca v.

Nhng cây g không đưc x lý trong cây conv, s trôi đn nút p( p nm trên đưng t v đnr).

• C[i, s, v] vi i, s, v có ý nghĩa tương t như trênnhưng đim khác là nhng cây g chưa đưc

Nguyn Hu Đin 13/15 http://nhdien.wordpress.com

Page 14: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 14/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

x lý s đưc chuyn đn mt nhà máy đt tiv.

Ta s tính đưc mng B theo công thc sau:

• B[0, s, v, p] = 0

• B[i, s, v, p] = min(B[i−1, s− j, v, p] + A[vi, j, p])

vi 0 ≤ j ≤ s.

Còn mng C s đưc tính theo công thc sau:

• C[0, s, v] = 0

• C[i, s, v] = min(C[i−1, s− j, v] + A[vi, j, depth(v)])

vi 0 ≤ j ≤ s.

Da vào ý nghĩa A1, A2, B,C ta có th nhn thy:

• A1[v, t, p] = B[deg(v), t, v, p]

• A2[v, t] = C[deg(v), t− 1, v]

Đ tính mi giá tr A1[v, t, p] (cũng như A2[v, t])vi p thuc {0..depth(v)}, chúng ta tính B[i, s, v, p]

(cũng như C[i, s, v]) vi i = 0 , . . . ,deg(v) vàs = 0 , . . . , k. Như vy vi mi cp v, p ta tínhđưc trong O(k2(deg(v) + 1)). Đ tính toàn b A, B,C ta mt O(n∑ k2(deg(v) + 1)) = O(k2n2) vì

∑ deg(v) = n− 1.

Đáp s cui cùng là A1[r, k, 0].

Phương án cài đt

Chương trình 6: riv.pas

1 program riv;2 const3 maxn = 100;4 maxk = 50;5 var6 lch, fch, next, w, d : array [0.. maxn] of integer;7 f 1 , f 2 :8 array [1.. maxn, 0..maxn, −1..maxk] of  longword;9 dis : array [0.. maxn, 0..maxn] of  longword;

10 maxcost, maxDword : longword;11 n , k : integer;

13 procedure readdata;14 var15 i , f a : integer;16 begin17 readln(n, k);18 for i := 1 to n do19 begin20 readln(w[i ], fa, d[i ]);21 if  fch[ fa] = 0 then begin22 fch[fa] := i;23 lch[ fa] := i ;24 end25 else begin26 next[lch [ fa ]] := i ;

27 lch[fa] := i;28 end;29 end;30 end;

32 function min(x, y : double) : double;

33 begin34 if  x < y then min := x35 else min := y;36 if  min > maxDword then37 min := maxDword;38 end;39 procedure dp2(i, grand, k : integer); forward ;40 procedure dp1(i, grand, k : integer);41 begin42 if  f1[ i , grand, k] <> maxDword then exit;43 if  fch[ i ] <> 0 then begin44 dp2(fch[ i ], grand, k);45 dp2(fch[ i ], i , k−1);

46 f1[ i , grand, k] := round(min(f2[fch [ i ], grand, k]47 + dis[ i , grand] ∗ w[i ], f2[fch[ i ], i , k−1]));48 end49 else50 if  k = 1 then51 f1[i, grand, k] := 052 else if  k = 0 then53 f1[ i , grand, k] := round(min(dis[ i ,54 grand] ∗ w[i ], maxcost))55 else56 f1[ i , grand, k] := maxcost;57 end;

59 procedure dp2(i, grand, k : integer);60 var61 k1, k2 : integer;62 begin63 if  k = −1 then begin64 f2[ i , grand, k] := maxcost;65 exit ;66 end;67 if  f2[ i , grand, k] <> maxDword then exit;68 if  next[ i ] <> 0 then begin69 k2:=k;70 for k1 := 0 to k do begin71 dp1(i, grand, k1);72 dp2(next[ i ], grand, k2);73 f2[ i , grand, k] := round(min(f2[i , grand, k ],74 f1[ i , grand, k1] + f2[next[ i ], grand, k2])) ;75 dec(k2);76 end77 end78 else begin79 dp1(i, grand, k);80 f2[ i , grand, k] := f1[ i , grand, k ];81 end;82 end;

84 procedure dfs(root, i : integer; cost : longword);85 var86 ch : integer;

Nguyn Hu Đin 14/15 http://nhdien.wordpress.com

Page 15: laptrinh-02-2012

8/3/2019 laptrinh-02-2012

http://slidepdf.com/reader/full/laptrinh-02-2012 15/15

LP TRÌNH = ++THUT TOÁNS 2, 15 - 1 - 2012

87 begin88 dis[i, root] := cost;89 ch := fch[ i ];90 while ch <> 0 do begin91 dfs( root , ch, cost + d[ch]);92 ch := next[ch];

93 end;94 end;

96 procedure init;97 var98 i , j : integer;99 begin

100 for i := 0 to n do d f s ( i , i , 0 ) ;

101 maxDword := not maxDword;102 fillDword (f1 , sizeof (f1) shr 2,maxDword);103 fillDword (f2 , sizeof (f2) shr 2,maxDword);104 maxcost := 2000000001;105 end;

107 begin108 readdata;109 init ;110 dp2(fch [0], 0, k);111 writeln(f2[fch [0], 0, k]) ;112 end.