1. Trang chủ
  2. » Công Nghệ Thông Tin

Hướng dẫn một số bài trên SPOJ

53 5,7K 5

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 53
Dung lượng 1,24 MB

Nội dung

CÁC BÀI TOÁN DUYỆT 1. Robot quét vôi ( http:vn.spoj.plproblemsNKROBOT ) 2. DÃY ABC 3. BÀI TOÁN NGƯỜI DU LỊCH 4. Tour du lịch của Sherry ( http:vn.spoj.plproblemsLEM3 ) CÁC THAO TÁC XỬ LÝ BIT 1. Số đặc biệt: 2. Xâu cô lập: 3. Liệt kê tập con: DUYỆT BẰNG CÁCH CHIA ĐÔI TẬP HỢP 3. Nhà hàng Trung Quốc ( http:vn.spoj.plproblemsCHNREST ) 4. Phân tập ( http:vn.spoj.plproblemsLQDDIV ) TÌM KIẾM NHỊ PHÂN QUY HOẠCH ĐỘNG

Trang 1

CÁC BÀI TOÁN DUYỆT

1 Robot quét vôi ( http://vn.spoj.pl/problems/NKROBOT )

Có 9 căn phòng (đánh số từ 1 đến 9) đã được quét vôi với màu trắng, xanh hoặc vàng Có 9 robot (đánh số từ 1 đến 9) phụ trách việc quét vôi Mỗi robot chỉ quét một số phòng nhất định Việc quét vôi được thực hiện nhờ một chương trình cài sẵn theo qui tắc:

Nếu phòng đang có màu trắng thì quét màu xanh

Nếu phòng đang có màu xanh thì quét màu vàng

Nếu phòng đang có màu vàng thì quét màu trắng

Cần phải gọi lần lượt một số các robot ra quét vôi (mỗi lần một robot, một robot có thể gọi nhiều lần và có thể có robot không được gọi Robot được gọi sẽ quét vôi tất cả các phòng mà nó phụ trách) để cuối cùng các phòng đều có màu trắng

Yêu cầu: Hãy tìm một phương án như vậy sao cho số lần gọi robot là ít nhất Giả thiết rằng lượng

vôi cho mỗi lượt quét đối với các phòng là như nhau

Input

9 dòng đầu: dòng thứ i mô tả một danh sách các phòng do robot i phụ trách việc quét vôi Mỗi dòng là một chuỗi các chữ số từ 1 9 biểu diễn các số hiệu của các phòng, các chữ số viết sát nhau

Dòng cuối mô tả mầu vôi ban đầu của các phòng Dòng gồm 9 ký tự viết sát nhau gồm toàn các chữ cái T (trắng), X (xanh), V(vàng) biểu diễn mầu ban đầu của 9 căn phòng theo trật tự số hiệu của chúng

Output

gồm một dòng

Nếu không có phương án thì in ra số 0

Trái lại thì in ra dãy thứ tự các robot được gọi (số hiệu các robot được viết sát nhau và in

Trang 2

Tại bước thử chọn Xi, nếu ta đã có Ti ký tự "C" trong đoạn đã chọn từ X1 đến Xi, thì cho dù các bước đệ quy tiếp sau làm tốt như thế nào chăng nữa, số ký tự "C" sẽ phải chọn thêm bao giờ cũng (n - i) div 4 Tức là nếu theo phương án chọn Xi như thế này thì số ký tự "C" trong dãy kết quả (khi chọn đến Xn) cho dù có làm tốt đến đâu cũng T i + (n - i) div 4 Ta dùng con số này để

đánh giá nhánh cận, nếu nó nhiều hơn số ký tự "C" trong “Cấu hình tối ưu” thì chắc chắn có làm tiếp cũng chỉ được một cấu hình tồi tệ hơn, ta bỏ qua ngay cách chọn này và thử phương án khác

Các bạn tham khảo Code:

Trang 3

if j = 'C' then T[i] := T[i - 1] + 1

else T[i] := T[i - 1];

if T[i] + (N - i) div 4 < MinC then

3 BÀI TOÁN NGƯỜI DU LỊCH

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 Cij = Cji = 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 Cii = 0 với i, Cij = + 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

(Traveling Salesman)

Trang 4

1 2

3 4

3

4 2

Hướng dẫn:

Hành trình cần tìm có dạng (x1 = 1, x2, …, xn, xn+1 = 1) ở đây giữa xi và xi+1: hai thành phố liên tiếp trong hành trình phải có đường đi trực tiếp (Cij + ) và ngoại trừ thành phố 1, không thành phố nào được lặp lại hai lần Có nghĩa là dãy (x1, x2, …, xn) lập thành 1 hoán vị của (1, 2, …, n) Duyệt quay lui: x2 có thể chọn một trong các thành phố mà x1 có đường đi tới (trực tiếp), với mỗi cách thử chọn x2 như vậy thì x3 có thể chọn một trong các thành phố mà x2 có đường đi tới (ngoài

x1) Tổng quát: xi 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)

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 xi 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ị xn ta kiểm tra xem xn 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ố xn cộng với chi phí từ xn đ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

Sau thủ tục tìm kiếm quay lui mà chi phí của BestConfig vẫn bằng + thì có nghĩa là nó không tìm thấy một hành trình nào thoả mãn điều kiện đề bài để cập nhật BestConfig, bài toán không có lời giải, còn nếu chi phí của BestConfig < + thì in ra cấu hình BestConfig - đó là hành trình ít tốn kém nhất tìm được

Input: file văn bản TOURISM.INP

Dòng 1: Chứa số thành phố n (1 n 20) và số tuyến đường m trong mạng lưới giao thông

m dòng tiếp theo, mỗi dòng ghi số hiệu hai thành phố có đường đi trực tiếp và chi phí đi trên quãng đường đó (chi phí này là số nguyên dương 100)

Output: file văn bản TOURISM.OUT, ghi hành trình tìm được

Trang 5

Các bạn tham khảo Code:

C: array[1 max, 1 max] of longint;

X, BestWay: array[1 max + 1] of longint;

Trang 6

procedure Try(i: longint);

T[i] := T[i - 1] + C[x[i - 1], j];

if T[i] < MinSpending then

BestWay := X;

MinSpending := T[n] + C[x[n], 1]; end;

Assign(f, OutputFile); Rewrite(f);

if MinSpending = maxC then WriteLn(f, 'NO SOLUTION') else

for i := 1 to n do Write(f, BestWay[i], '->'); WriteLn(f, 1);

WriteLn(f, 'Cost: ', MinSpending);

Trang 7

4 Tour du lịch của Sherry ( http://vn.spoj.pl/problems/LEM3 )

Trong kì nghỉ hè năm nay sherry được bố thưởng cho 1 tour du lịch quanh N đất nước tươi đẹp với nhiều thắng cảnh nổi tiếng ( vì sherry rất ngoan ) Tất nhiên sherry sẽ đi bằng máy bay

Giá vé máy bay từ đất nước i đến đất nước j là Cij ( dĩ nhiên Cij có thể khác Cji ) Tuy được bố thưởng cho nhiều tiền để đi du lịch nhưng sherry cũng muốn tìm cho mình 1 hành trình với chi phí

rẻ nhất có thể để dành tiền mua quà về tặng mọi người ( Các chuyến bay của sherry đều được đảm bảo an toàn tuyệt đối )

Bạn hãy giúp sherry tìm 1 hành trình đi qua tất cả các nước, mỗi nước đúng 1 lần sao cho chi phí

Điểm của mỗi bài không bé hơn điểm của bài trước đó

Số điểm của mỗi bài bằng điểm đề nghị cho bài này của một vị giám khảo nào đó

Dữ liệu

Dòng đầu tiên chứa ba số nguyên S (1 ≤ S ≤ 200), (1 ≤ K ≤ 20), (1 ≤ N ≤ 20)

Dòng thứ i trong số N dòng tiếp theo chứa K số nguyên, số thứ j cho biết giá trị Aij là số điểm vị giám khảo thứ i đề nghị cho bài thứ j

Kết qủa

Nếu tồn tại một cách cho điểm thỏa mãn yêu cầu:

o Dòng thứ nhất: in ra 'YES'

o Dòng thứ hai: in ra K số nguyên là điểm của mỗi bài tìm được

Nếu không tồn tại cách cho điểm, in ra 'NO'

Trang 8

Ví dụ

Hướng dẫn:

Kết quả của bài toán (nếu có) sẽ có dạng X1X2…Xk Trong mỗi bước duyệt, ta sẽ thử chọn Xi trong tập Aji (1 <= j <= n) Sau khi chọn Xi, ta có thể đánh giá được Smin (tổng điểm bé nhất có thể đạt được khi duyệt xong) bằng dữ kiện dãy X tăng dần

S min (tổng điểm khi chọn xong) = P[i] + X[i] * (k-i) với P[i] là tổng điểm đã có

- Smin <= S : duyệt tiếp bài toán vẫn có thể có nghiệm

- Smin > S : vô nghiệm

Đó cũng chính là cận trong quá trình duyệt để chương trình có thể chạy trong thời gian cho phép!

6 Hoán vị chữ cái ( http://vn.spoj.pl/problems/QBHV )

Cho một xâu S chỉ gồm các chữ cái in hoa, 1 <= độ dài <= 9

Yêu cầu:

1: Có bao nhiêu cách hoán vị các chữ cái của xâu S

2: Liệt kê các hoán vị đó theo thứ tự từ điển

Input

Gồm 1 dòng duy nhất chứa xâu S

Output

Dòng 1: Ghi số lượng hoán vị tìm được (K)

K dòng tiếp theo, mỗi dòng ghi một xâu hoán vị của xâu S theo đúng thứ tự từ điển

Trang 9

Công thức: Result = N! div (Count[ch])

với N là độ dài của S và Count[ch] là số lần xuất hiện của ký tự "ch"

7 Quan hệ ( http://vn.spoj.pl/problems/COND )

Xét một tập N đối tượng có thể so sánh được (2<=n<=10) Giữa 2 đối tượng a và b có thể tồn tại

1 trong 3 quan hệ phân loại:

Trang 10

Thế thì số quan hệ phân loại loại này bằng: n! / (a1! * a2! * a3! * * ak!)

Tóm lại công thức cuối cùng bằng:

Sum ( n! / (a1! * a2! * * ak!) | a1 + a2 + + ak <= n)

8 Quan hệ có điều kiện ( http://vn.spoj.pl/problems/QBCOND )

Ngày nay khi nghiên cứu quan hệ giữa các phần tử các nhà khoa học không đơn giản chỉ nghiên cứu các quan hệ bình thường mà để thêm phần phức tạp là thêm vào đó 1 vài bộ điều kiện Một trong những điều kiện đó là số quan hệ '='

Như ta đã biết giữa 2 phần tử a, b sẽ có 3 quan hệ:

a = b, a > b, a < b

Các nhà khoa học đưa ra 1 bộ gồm n phần tử Sau khi tìm ra số lượng các quan hệ của n phần tử này họ muốn biết nếu như số quan hệ '=' trong tập n phần tử này đúng bằng k thì sẽ có bao nhiêu quan hệ như thế?

Trang 11

CÁC THAO TÁC XỬ LÝ BIT

Dưới đây là những kiến thức về việc sử dụng các phép toán logic từ đó giúp cho việc thiết kế các biểu thức logic dùng rất nhiều trong các phép toán điều kiện được nhanh chóng, chính xác, hiệu quả

* Quy ước về vị trí của các bit:

Mỗi byte bao gồm 8 bit được mã số từ phải sang trái còn gọi là bit thấp đến bit cao Bit nằm ở bên phải được xem là thấp hơn bit nằm ở bên trái Các bit được đánh số như sau: 7 6 5 4 3 2 1 0 Mỗi bit có thể nhận 1 trong 2 giá trị là 0 hoặc 1 Tại mỗi thời điểm thực hiện chương trình mỗi bit đươc nhận giá trị xác định Mọi số nguyên trong máy đều biểu diễn dưới dạng nhị phân, thí dụ số

19 được biểu diễn như sau:

Bit 7 6 5 4 3 2 1 0

Giá trị 0 0 0 1 0 0 1 1 (số 19)

* Các phép toán logic

Các phép toán sau đây thực hiện trên các giá trị nguyên và cho kết quả là các giá trị nguyên

1 Phép đảo bit NOT : đổi giá trị của mọi bit từ 0 thành 1 và ngược lại

2 Phép cộng logic trên các bit OR thực hiện trên từng cặp bit tương ứng của các toán hạng

theo bảng cộng sau:

Quy tắc: Tổng hai bit bằng 0 khi và chỉ khi cả hai bit bằng 0 ngoài ra tổng nhận giá trị 1 Phép OR

còn được gọi là phép “hoặc”

3 Phép nhân logic trên các bit AND : thực hiện trên từng cặp bit tương ứng của các toán hạng

theo bảng nhân sau:

Quy tắc: Tích hai bit bằng 1 khi và chỉ khi cả hai bit bằng 1, ngoài ra tích nhận giá trị 0 Phép AND

Trang 12

4 Phép cộng loại trừ trên các bit ( XOR ) : thực hiện trên từng cặp bit tương ứng của các toán

x SHR i : Phép dịch phải, cho giá trị có được từ số nguyên x sau khi dịch sang phải i bit

x SHL i : Phép dịch trái, cho giá trị có được từ số nguyên x sau khi dịch sang trái i bit

Với x = 2 ta có:

Trên đây là một số phép toán làm việc trên các bit mà ta hay dùng, trên cơ sở đó, ta xây dựng được một số hàm, thủ tục hay dùng sau

1 Hàm lấy giá trị bit: Hàm trả về giá trị 0 hoặc 1

Function GetBit(x, i:longint):longint;

Begin

GetBit:=(x SHR i) and 1;

End;

2 Thủ tục bật bit: Thủ tục gán trị 1 cho bit thứ i trong số nguyên x.

Procedure OnBit(Var x:longint; i:longint);

Begin

x:=x OR (1 SHL i);

End;

3 Thủ tục tắt bit: Thủ tục gán trị 1 cho bit thứ i trong số nguyên x

Procedure OffBit(Var x:longint; i:longint);

Trang 13

1 Số đặc biệt:

Xét một dãy gồm N số nguyên A1, A2, A3, An Trong dãy số trên có 1 số chỉ xuất hiện đúng một lần, và các số còn lại xuất hiện một số chẵn lần

Yêu cầu: Hãy tìm số đặc biệt của một dãy cho trước

Dữ liệu: Trong file văn bản SDB gồm:

- Dòng đầu là số N (N ≤ 107)

- N dòng tiếp, dòng thứ i là Ai với |Ai| ≤ 109

Kết quả: Một dòng duy nhất là số cần tìm

Ví dụ:

Hướng dẫn: Lần lượt thực hiện phép XOR số thứ 1 với số thứ 2, lấy kết quả thực hiện với số thứ

3 và cứ thế cho hết N số Vì phép XOR là phép “triệt tiêu”, do đó kết quả cuối cùng là số chỉ xuất hiện 1 lần (không bị triệt tiêu) Bằng cách biểu diễn các số dưới dạng nhị phân rồi thực hiện phép XOR, các bạn có thể dễ dàng chứng minh được thuật toán trên là đúng đắn

res := 0;

For i := 1 to N do begin

Yêu cầu: Tìm xâu cô lập từ N xâu đã cho

Dữ liệu: Trong file văn bản SINGLE.INP gồm

N dòng biểu diễn N xâu đã cho ban đầu

Kết quả: Một dòng duy nhất là xâu cô lập

Trang 14

3 Liệt kê tập con:

Cho tập hợp gồm N phần tử ( 1 ≤ N ≤ 20 ) Hãy liệt kê tất cả các tập con (kể cả rỗng) của tập hợp

đã cho

Hướng dẫn: Xem như N phần tử là dãy N bit Ta có thể biểu diễn tất cả các tập con bằng dãy N bit, giá trị 1 (hoặc 0) biểu diễn sự tồn tại (hoặc không tồn tại) của mỗi phần tử Giá trị dãy bit tương ứng từ 0 2n - 1 Để kiểm tra sự tồn tại của 1 phần tử trong dãy bit có giá trị x, ta sử dụng hàm GetBit như đã nêu trên Đây là 1 bài toán rất cơ bản, các bạn có thể tự code

Trang 15

DUYỆT BẰNG CÁCH CHIA ĐÔI TẬP HỢP

1 Tổng vector ( http://vn.spoj.pl/problems/VECTOR )

Trong mặt phẳng tọa độ có N véc tơ Mỗi một véc tơ được cho bởi hai chỉ số x và y Tổng của hai véc tơ (xi, yi) và (xj, yj) được định nghĩa là một véc tơ (xi + xj, yi + yj) Bài toán đặt ra là cần chọn một số véc tơ trong N véc tơ đã cho sao cho tổng của các vec tơ đó là véc tơ (U, V)

Yêu cầu: Đếm số cách chọn thoả mãn yêu cầu bài toán đặt ra ở trên.

- Chia tập N vector thành 2 tập bằng nhau A và B

- Gọi F[x, y] là số cách chọn để có vector tổng (x, y) trên tập A Để tính F[x, y] thì ta sẽ duyệt tất

cả các tập con của tập A, sau khi tính được vector tổng của mỗi tập con ta chỉ việc inc(F[x, y])

- Tương tự ta sẽ duyệt trên tập B, sau khi tính được vector tổng (x1, y1) của mỗi tập con ta sẽ

inc(Res, F[U - x1, V - y1]) với Res là kết quả của bài toán

Việc duyệt tập con của tập A, B có thể cài đặt như bài toán ở phần trước đã nhắc tới!

Trang 16

for n := 4 to 34 do

xu [n] có giá trị (xu[n-1] + xu[n-2] + xu[n-3])

Bạn hãy dùng nhiều đồng xu nhất để mua một món hàng có giá là X

Hướng dẫn: Gọi T[i] là số đồng xu nhiều nhất có thể mua món hang có giá trị là i Trong mỗi

bước duyệt ở tập thứ 2, ta tiến hành cập nhật T[i]: T[i] := Max(T[i], F[i - x] + y) với x là

khối lượng tập hợp con, y là số lượng xu của tập Mảng F có ý nghĩa tương tự T và đã được tính trước ở bước 1

3 Nhà hàng Trung Quốc ( http://vn.spoj.pl/problems/CHNREST )

Hàng năm vì muốn có không khí ấm cúng và cũng để tiết kiệm nên bạn thường tổ chức sinh nhật

ở nhà Tuy nhiên trước sinh nhật năm nay vài hôm bạn đã thi đậu vào đội tuyển tin học quốc gia Đây là một sự kiện đặc biệt có ý nghĩa nên bạn quyết định mừng ngày sinh nhật của mình tại một nhà hàng Trung Quốc sang trọng và bạn tự nhủ lần này nhất định phải tiêu xài rộng tay hơn Mọi việc chuẩn bị đã gần xong nhưng còn một vấn đề làm bạn khá nhức đầu, đó là làm sao chọn được những món ăn mà mọi người cùng thích

Nhà hàng có M món ăn khác nhau và thú vị ở chỗ là mỗi món ăn rất nhiều nên có thể đủ cho bao nhiêu người cũng được, vì thế vấn đề là gọi món nào chứ không phải mỗi món gọi bao nhiêu Có tất cả N người đến dự tiệc sinh nhật (bao gồm cả bạn trong đó) Bạn đã tìm hiểu được danh sách những món ăn yêu thích của từng người và bạn muốn rằng đối với mỗi người phải có ít nhất 2 món mà họ thích Tuy nhiên sau khi ăn xong còn nhiều tiết mục hấp dẫn khác nên bạn cũng muốn rằng bất kỳ ai cũng không có quá 2 món ăn yêu thích trong danh sách được đặt trước Và vấn đề cuối cùng, đây là tiền của bố mẹ nên cũng không nên tiêu xài quá đáng

Trang 17

Yêu cầu

Hãy cho biết số tiền ít nhất phải trả để gọi một thực đơn thỏa mãn các yêu cầu trên

Dữ liệu

- Dòng đầu tiên chứa hai số M, N

- Dòng thứ hai chứa M số Pi là giá của món thứ i

- Trong N dòng cuối cùng, dòng thứ k ghi danh sách các món yêu thích của người thứ k

Kết quả

- Gồm một số duy nhất là kết quả của bài toán, hoặc

- in ra -1 nếu không có cách gọi món nào thỏa mãn

tự với lần thứ 2 là B1, B2, B3, , Bn (Với Ai, Bi <= 2 và Ai + Bi = 2) Chúng ta tìm cách mã hóa dãy

A, B thành số tự nhiên để tiện cho việc lưu trữ và tính toán

4 Phân tập ( http://vn.spoj.pl/problems/LQDDIV )

Cho N người(2≤N≤32) ,mỗi người có một số ai(1 ≤ ai ≤ 109) được gọi là độ tin cậy

Cần phân chia n người này vào 2 tập sao cho:

- Mỗi người thuộc đúng một tập

- Chênh lệch tổng độ tin cậy của 2 phần là bé nhất

Input

Dòng đầu chứa số nguyên N

Dòng tiếp theo chứa N số : số thứ i là độ tin cậy của người thứ i

Output

Ghi ra hai số u và v với u là độ chênh lệch nhỏ nhất và v là số cách phân chia

Example

Trang 18

Có 3 cách phân chia 3 cách phân chia nhóm 1 là (3,5) ,(1,3,4) và (1,2,5)

Hướng dẫn: Tư tưởng của bài toán vẫn là chia đôi để duyệt Ta sẽ chọn một số người ở lần duyệt thứ nhất và một số người ở lần duyệt thứ hai để cho vào “nhóm 1”

Giả sử tổng độ tin cậy lần duyệt thứ nhất là x, thứ hai là y, gọi S là tổng độ tin cậy của N người Tổng độ tin cậy của “nhóm 1” trong TH này là x + y, và của “nhóm 2” là S - (x + y) Độ chênh lệch tạo thành là Abs(S - (x + y) - (x + y)) = Abs(S - 2*(x+y)) Cách giải quyết cụ thể như sau :

- Duyệt N div 2 người, các tổng độ tin cậy thu được lưu vào một mảng C có tối đa là 216 phần tử

Để tiện cho tính toán sau này, ta sẽ tối ưu mảng bằng cách loại bỏ những tổng bằng nhau và chỉ giữ lại một, đồng thời dùng thêm 1 mảng để đếm số lần xuất hiện của tổng đó (cần sắp xếp lại mảng C trước khi tối ưu nó) Ví dụ D[i] là số lần xuất hiện của tổng độ tin cậy C[i]

- Duyệt phần còn lại, mỗi tổng độ tin cậy X sinh ra, ta sẽ tìm C[i] sao cho Abs(S - 2*(X+C[i])) nhỏ nhất có thể Sau đó cập nhật kết quả tối ưu Tìm kiếm nhị phân giá trị C[i] sẽ là rất hợp lí bởi mảng C đã được sắp xếp và kích thước của nó cũng khá lớn

Trang 19

TÌM KIẾM NHỊ PHÂN

Các bạn có thể tham khảo kỹ thuật tìm kiếm nhị phân ở các tài liệu khác Trong tài liệu này, chúng

ta sẽ lướt qua một vài ví dụ thật cơ bản để các bạn có thể hiểu thêm về nó

1 Tải trọng của tuyến đường

Một hệ thống giao thông liên thông gồm N thành phố với tên 1 N (N <= 100) Có một số đoạn đường hai chiều giữa một số cặp thành phố và mỗi đoạn đường có một tải trọng tối đa mà chỉ có các xe với tải trọng không lớn hơn mới đi qua được

Cần đi từ thành phố U tới V Hãy tìm một hành trình sao cho tải trọng tối đa cho phép trên hành trình đó là lớn nhất có thể được

Dữ liệu : Trong file văn bản TAITRONG.INP gồm

Dòng đầu là 3 số N, U, V

Tiếp theo là một số dòng, mỗi dòng ghi ba số nguyên dương X Y Z với ý nghĩa có đường đi giữa X và Y với tải trọng tối đa cho phép là Z (0 < Z <= 10000)

Kết quả : Ra file văn bản TAITRONG.OUT gồm

Dòng thứ nhất ghi tải trọng H tối đa của xe có thế

Trong các dòng tiếp, mỗi dòng ghi tên một thành phố trong hành trình từ U kết thúc tại V

Ví dụ :

Hướng dẫn:

Đặt Hmin = Min(a[i, j]), Hmax = Max(a[i, j]) Với mỗi giá trị h ( Hmin ≤ h ≤ Hmax ) ta xây dựng đồ thị G(h) thỏa mãn: - N đỉnh tương ứng với N thành phố

- 2 đỉnh i, j có cạnh nối nếu a[i, j] ≥ h

Như vậy, nếu ta tìm thấy được một đường đi từ U tới V thì ta nói rằng : "Mạng giao thông có tải trọng tối thiểu h" Bài toán trở thành "Tìm giá trị h lớn nhất để tồn tại đường đi từ U tới V"

Ta sẽ sử dụng kỹ thuật tìm kiếm nhị phân dựa theo nhận xét: Nếu mạng có tải trọng tối thiểu k,

và h là giá trị lớn nhất để "mạng giao thông có tải trọng tối thiểu h" thì k ≤ h ≤ Hmax Ngược lại, nếu không có lộ trình với tải trọng tối thiểu là k thì Hmin ≤ h < k

Với mỗi giá trị h, có thể duyệt DFS hoặc BFS để kiểm tra tồn tại đường đi từ U tới V hay không

Trang 20

Dòng đầu ghi số nguyên dương N

Dòng tiếp theo ghi N số ri ( 1 ≤ i ≤ N )

Khi R thỏa mãn yêu cầu, ta có: O 1 OO 2 + O 2 OO 3 + O 3 OO 4 + + O n-1 OO n = 2pi (*)

Dễ dàng tính được các góc này theo độ dài 3 cạnh của các tam giác tương ứng Để tìm R thỏa

mãn, ta sẽ chia nhị phân giá trị của R với Rmin = 0 và Rmax = tổng các Ri Giá trị R thỏa mãn (*)

chính là nghiệm của bài toán

Chú ý xử lý dữ liệu tránh việc sai số khá lớn khi làm việc với số thực

Trang 21

QUY HOẠCH ĐỘNG

Quy hoạch động là dạng bài toán khá phổ biến trong các kỳ thi HSG môn Tin học Mục đích của chúng là giải quyết các bài toán tối ưu Vì không có một thuật toán tổng quát để giải tất cả các bài toán quy hoạch động, do đó các ví dụ sau đây giúp các bạn làm quen và tiếp cận một số dạng toán quy hoạch động

1 Đi xem phim ( http://vn.spoj.pl/problems/VCOWFLIX )

Nông dân John đang đưa các con bò của anh ta đi xem phim! Xe tải của anh ta thì có sức chứa có hạn thôi, là C (100 <= C <= 5000) kg, anh ta muốn đưa 1 số con bò đi xem phim sao cho tổng khối lượng của đống bò này là lớn nhất, đồng thời xe tải của anh ta vẫn chịu được

Cho N (1 <= N <= 16) con bò và khối lượng W_i của từng con, hãy cho biết khối lượng bò lớn nhất mà John có thể đưa đi xem phim là bao nhiêu

Dữ liệu

Dòng 1: 2 số nguyên cách nhau bởi dấu cách: C và N

Dòng 2 N+1: Dòng i+1 chứa 1 số nguyên: W_i

81+58+42+61 = 242; đây là tổng khối lượng bò lớn nhất có thể được

Hướng dẫn: Sử dụng mảng F : boolean với ý nghĩa F[i] = true nếu có cách chọn các con bò để

có khối lượng là i và ngược lại

Trang 22

Chơi đến đây, Bờm chợt nảy ra câu hỏi: có bao nhiêu cách để Lucky leo hết được cầu thang? (nghĩa là leo đến bậc thang thứ n) Bờm muốn nhờ bạn trả lời câu hỏi này

Yêu cầu: Xác định xem những người nào cần rời khỏi hàng và nhờ người đứng trước mua hộ vé để tổng thời gian phục vụ bán vé là nhỏ nhất.

Trang 23

Dữ liệu

Dòng đầu tiên chứa số N (1 ≤ N ≤ 60000)

Dòng thứ 2 ghi N số nguyên dương t1, t2, , tN (1 ≤ ti ≤ 30000)

Dòng thứ ba ghi N-1 số nguyên dương r1, r2, , rN-1 (1 ≤ ri ≤ 30000)

Hướng dẫn: Gọi F[i] là thời gian ít nhất để i người đầu tiên mua vé xong

Ta có công thức QHĐ F[i] := Max(F[i-1] + T[i], F[i-2] + R[i-1])

Độ phức tạp O(n)

4 Nối mạng ( http://vn.spoj.pl/problems/NKCABLE )

Các học sinh khi đến thực tập trong phòng máy tính thường hay chơi trò chơi điện tử trên mạng

Để ngăn ngừa, người trực phòng máy đã ngắt tất cả các máy tính ra khỏi mạng và xếp chúng thành một dãy trên một cái bàn dài và gắn chặt máy xuống mặt bàn rồi đánh số thứ tự các máy

từ 1 đến N theo chiều từ trái sang phải Các học sinh tinh nghịch không chịu thua, họ đã quyết định tìm cách nối các máy trên bàn bởi các đoạn dây nối sao cho mỗi máy được nối với ít nhất một máy khác Để tiến hành công việc này, họ đã đo khoảng cách giữa hai máy liên tiếp Bạn hãy giúp các học sinh này tìm cách nối mạng thoả mãn yêu cầu đặt ra sao cho tổng độ dài cáp nối phải sử dụng là ít nhất

Dữ liệu

Dòng đầu tiên chứa số lượng máy N (1 ≤ N ≤ 25000)

Dòng thứ i trong số N-1 dòng tiếp theo chứa các khoảng cách từ máy i đến máy i+1

(i=1,2, ,N-1) Giả thiết rằng khoảng cách từ máy 1 đến máy N không vượt quá 106

Kết quả

Ghi ra độ dài của cáp nối cần sử dụng

Trang 24

Hướng dẫn: Gọi F[i] là độ dài của cách nối mạng ngắn nhất xét từ máy 1 i

Ta có F[i] := Min(F[i-2], F[i-1]) + L[i-1];

Thời gian O(n)

5 Mua vé tàu hỏa ( http://vn.spoj.pl/problems/QBTICKET )

Tuyến đường sắt từ thành phố A đến thành phố B đi qua một số nhà ga Tuyến đường có thể biểu diễn bởi một đoạn thẳng, các nhà ga là các điểm trên đó Tuyến đường bắt đầu từ A và kết thúc ở

B, vì thế các nhà ga sẽ được đánh số bắt đầu từ A (có số hiệu là 1) và B là nhà ga cuối cùng Giá vé đi lại giữa hai nhà ga chỉ phụ thuộc vào khoảng cách giữa chúng Cách tính giá vé như sau: Khoảng cách giữa hai nhà ga (X)

Khoảng cách 0 < X <= L1 -> Giá vé C1

Khoảng cách 0 < X <= L2 -> Giá vé C2

Khoảng cách 0 < X <= L3 -> Giá vé C3

Nghĩa là với các giá vé C1, C2, C3 tương ứng bạn sẽ đi quảng đường tối đa là L1, L2, L3

Vé để đi thẳng từ nhà ga này đến nhà ga khác chỉ có thể đặt mua nếu khoảng cách giữa chúng không vượt quá L3 Vì thế nhiều khi để đi từ nhà ga này đến nhà ga khác ta phải đặt mua một số

vé Hơn thế nữa, nhân viên đường sắt yêu cầu hành khách chỉ được giữ đúng một vé khi đi trên tàu và vé đó sẽ bị huỷ khi hành khách xuống tàu

Yêu cầu: Tìm cách đặt mua vé để đi lại giữa hai nhà ga cho trước với chi phí mua vé là nhỏ nhất

Input

Dòng đầu tiên ghi các số nguyên L1, L2, L3, C1, C2, C3 (1 <= L1 <= L2 <= L3 <= 109; 1 <= C1

<= C2 <= C3 <= 109) theo đúng thứ tự liệt kê ở trên

Dòng thứ hai chứa số lượng nhà ga N ( 2 <= N <= 100000 )

Dòng thứ ba ghi hai số nguyên s, f là các chỉ số của hai nhà ga cần tìm cách đặt mua vé với chi phí nhỏ nhất để đi lại giữa chúng

Dòng thứ i trong số N - 1 dòng tiếp theo ghi số nguyên là khoảng cách từ nhà ga A (ga 1) đến nhà

ga thứ i + 1

Output

Gồm 1 dòng duy nhất ghi chi phí nhỏ nhất tìm được

Trang 25

Hướng dẫn: Gọi F[i] là chi phí ít nhất để đi đến ga i trên chặng từ s đến f

Ta có F[i] := Min( F[i], F[j] + Chi phí từ j -> i )

Chú ý: Cài đặt khéo léo tránh TLE (Time Limit Exceeded)

6 Dạo chơi bằng xe buýt ( http://vn.spoj.pl/problems/KMBUS )

Một tuyến đường ở thành phố có các bến xe bus ở từng km tuyến đường Mỗi lần qua bến, xe đều

đỗ để đón khách Mỗi bến đều có điểm xuất phát Một xe chỉ chạy không quá B km kể từ điểm xuất phát của nó Hành khách khi đi xe sẽ phải trả tiền cho độ dài đoạn đường mà họ ngồi trên

xe Cước phí cần trả để đi đoạn đường độ dài i là Ci(i=1,2 B) Một du khách xuất phát từ 1 bến nào đó muốn đi dạo L km theo tuyến nói trên Hỏi ông ta phải lên xuống xe như thế nào để tổng

số tiền phải trả là nhỏ nhất có thể

Dữ liệu vào:

Dòng đầu ghi 2 số nguyên dương B, L

Dòng thứ i trong số B dòng tiếp theo ghi 1 số nguyên dương Ci ( 1 ≤ i ≤ B )

Trang 26

Hướng dẫn: Gọi F[i] là số tiền ít nhất người đó phải trả khi đi i km

Ta có công thức QHĐ: F[i] := Min( F[i], F[i-j] + a[j]) với j <= i

7 Đổi tiền ( http://vn.spoj.pl/problems/DTDOI )

Bạn được cho một tập hợp các mệnh giá tiền Tập hợp luôn chứa phần tử mang gía trị 1 Mỗi mệnh giá có vô hạn các đồng tiền mang mệnh giá đó Cho số tiền S, hãy tìm cách đổi S thành ít đồng tiền nhất, sao cho mỗi đồng tiền có mệnh giá thuộc vào tập hợp đã cho

8 Hội trường ( http://vn.spoj.pl/problems/NKREZ )

Nhà trường có một phòng hội trường Có những yêu cầu muốn sử dụng phòng hội trường này, mỗi yêu cầu cho biết thời điểm bắt đầu và thời điểm kết thúc Nhà trường có thể chấp nhận hoặc

từ chối đối với một yêu cầu

Yêu cầu: hãy giúp nhà trường chọn các yêu cầu sử dụng hội trường sao cho tổng thời gian hội trường được sử dụng là lớn nhất

Dữ liệu

Dòng đầu tiên chứa một số nguyên dương n (n ≤ 10000), số yêu cầu

Mỗi dòng trong số n dòng tiếp theo chứa 2 số nguyên dương p và k (0 ≤ p < k ≤ 30000), mô tả một yêu cầu bắt đầu tại thời điểm p và kết thúc tại thời điểm k

Kết quả

Gồm một dòng duy nhất là tổng thời gian lớn nhất mà hội trường được sử dụng

Ví dụ

Dữ liệu:

Ngày đăng: 23/11/2014, 04:55

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w