Tải bản đầy đủ (.doc) (19 trang)

Gián án De on thi HSG mon Tin hoc

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 (270.36 KB, 19 trang )

Bài toán chúc Tết
Một người quyết định dành một ngày Tết để đến chúc Tết các bạn của mình. Để chắc chắn, hôm
trước anh ta đã điện thoại đến từng người để hỏi khoảng thời gian mà người đó có thể tiếp mình. Giả
sử có N người được hỏi (đánh số từ 1 đến N), người thứ i cho biết thời gian có thể tiếp trong ngày là
từ A
i
đến B
i
(i = 1, 2,..., N). Giả thiết rằng, khoảng thời gian cần thiết cho mỗi cuộc gặp là H và
khoảng thời gian chuẩn bị từ một cuộc gặp đến một cuộc gặp kế tiếp là T. Bạn hãy xây dựng giúp
một lịch chúc Tết để anh ta có thể chúc Tết được nhiều người nhất.
File dữ liệu vào trong file CHUCTET.INP gồm dòng đầu ghi số N, dòng thứ i trong số N dòng tiếp theo
ghi khoảng thời gian có thể tiếp khách của người i gồm 2 số thực A
i
và B
i
(cách nhau ít nhất một dấu
trắng). Dòng tiếp theo ghi giá trị H (số thực) và dòng cuối cùng ghi giá trị T (số thực). Giả thiết rằng
các giá trị thời gian đều được viết dưới dạng thập phân theo đơn vị giờ, tính đến 1 số lẻ (thí dụ 10.5
có nghĩa là mười giờ rưỡi) và đều nằm trong khoảng từ 8 đến 21 (từ 8 giờ sáng đến 9 giờ tối). Số
khách tối đa không quá 30.
Kết quả ghi ra file CHUCTET.OUT gồm dòng đầu ghi K là số người được thăm, K dòng tiếp theo ghi
trình tự đi thăm, mỗi dòng gồm 2 số (ghi cách nhau ít nhất một dấu trắng): số đầu là số hiệu người
được thăm, số tiếp theo là thời điểm gặp tương ứng.
Ví dụ
CHUCTET.INP
20
10.5 12.6
15.5 16.6
14.0 14.1
17.5 21.0


15.0 16.1
19.0 21.0
10.5 13.6
12.5 12.6
11.5 13.6
12.5 15.6
16.0 18.1
13.5 14.6
12.5 17.6
13.0 13.1
18.5 21.0
9.0 13.1
10.5 11.6
10.5 12.6
18.0 21.0
0.5
0.1
CHUCTET.OUT
16
17 9.0
1 10.5
18 11.1
19 11.7
8 12.3
10 12.9
11 13.5
13 14.1
5 15.0
2 15.6
12 16.2

14 16.8
4 17.5
7 19.0
16 19.6
20 20.2
Truyền tin trên mạng
Trong một mạng gồm n máy tính đánh số từ 1 đến N. Sơ đồ nối mạng đựơc cho bởi hệ thống gồm M
kênh nối trực tiếp giữa một số cặp máy tính trong mạng. Biết chi phí truyền một đơn vị thông tin theo
mỗi kênh nối của mạng.
Người ta cần chuyển một bức thông điệp từ máy S đến T. Để đảm bảo an toàn, người ta muốn
chuyển bức thông điệp này theo K đường truyền tin khác nhau. Hai đường truyền tin được gọi là khác
nhau nếu không có bất cứ kênh nối trực tiêp nào được dùng chung trên cả hai đường truyền tin. Chi
phí của một đường truyền tin được hiểu là chi phí trên các kênh của nó.
Yêu cầu
: Giả sử bức thông điệp có độ dài là 1 đơn vị thông tin, hãy tìm cách chuyển thông tin từ S
đến T sao cho tổng chi phí chuyển thông tin (bằng tổng chi phí theo cả K đường truyền tin) là nhỏ
nhất.
Dữ liệu:
Vào từ file văn bản Ttin.INP:
- Dòng đầu tiên ghi năm số N,M,S,T,K cách nhau bởi dấu cách (N≤100).
- M dòng sau mỗi dòng ghi ba số d
i
, c
i
, g
i
: trong đó d
i
, c
i

là chỉ số của hai máy tương ứng có kênh nỗi
và g
i
(nguyên dương) là chi phí để truyền một đơn vị thông tin từ máy d
i
đến máy c
i
và ngựơc lại
(i=1..n).
Kết quả:
Ghi ra file văn bản TTIN.OUT:
- Dòng đầu tiên ghi chi phí truyền thông điệp theo cách tìm đựơc
- K dòng tiếp theo, mỗi dòng ghi đường truyền tin dưới dạng dãy có thứ tự các máy bắt đầu từ máy S
và kết thúc ở máy T.
- Nếu không tìm đủ K đường đưa ra một dòng duy nhất: NO SOLUTION.
Ví dụ:
Số chung lớn nhất
Cho 2 xâu:
???? X = x
1
x
2
..x
M
. (Với x
i
là các kí tự số từ ?0? đến ?9?)
???? Y = y
1
y

2
..y
N
.( Với y
i
là các kí tự số từ ?0? đến ?9?)
(M, N <= 250)
Ta gọi: Z = z
1
z
2
..z
k
là xâu chung của 2 xâu X, Y nếu xâu Z nhận được từ xâu X bằng cách xoá đi một
số kí tự và cũng nhận được từ xâu Y bằng cách xoá đi một số kí tự.
Yêu cầu
: Tìm một xâu chung của 2 xâu X, Y sao cho xâu nhận được tạo thành một số lớn nhất có thể
được.
Dữ liệu vào file: String.inp
Gồm 2 dòng, dòng 1 là xâu X, dòng 2 là xâu Y.
Kết quả ra file: String.out
Gồm 1 dòng duy nhất là số lớn nhất có thể nhận được.
Ví dụ
:
String.inp String.out
19012304
034012
34
Ứng dụng luồng cực đại trong bài toán tối ưu rời rạc
I. Bài toán

Xét bài toán:
Trong đó a
ij
thuộc {0,1}
p
i
nguyên dương
i = 1,2,...,m;
j = 1,2,...,n
Bài toán trên là mô hình toán học của nhiều bài toán tối ưu tổ hợp trong thực tế. Ví dụ:
II. Ví dụ
1. Bài toán phân nhóm sinh hoạt:
Có m sinh viên và n nhóm sinh hoạt chuyên đề.Với mỗi sinh viên i biết:
- a
ij
=1, nếu sinh viên i có nguyện vọng tham gia vào nhóm j
- a
ij
=0, nếu ngược lại
- p
i
là số lượng nhóm chuyên đề mà sinh viên i phải tham dự
i=1,2,...,m; j=1,2,...,n
Trong số các cách phân các sinh viên vào nhóm chuyên đề mà họ có nguyện vọng tham gia và đảm
bảo mỗi sinh viên i phải tham gia đúng p
i
nhóm, hãy tìm cách phân phối với số người trong nhóm có
nhiều sinh viên tham gia nhất là nhỏ nhất có thể được.
Đưa vào các biến số:
x

ij
=1, nếu sinh viên i tham gia vào nhóm j
x
ij
= 0, nếu ngược lại
i=1, 2,...,m ; j=1, 2,...,n, khi đó dễ thấy mô hình toán học cho bài toán đặt ra chính là bài toán (1)-
(2).
2. Bài toán lập lịch cho hội nghị:
Một hội nghị có m tiểu ban, mỗi tiểu ban cần sinh hoạt trong một ngày tại phòng họp phù hợp với nó.
Có n phòng họp dành cho việc sinh hoạt của các tiểu ban.
Biết:

- a
ij
=1, nếu phòng họp i là thích hợp với tiểu ban j
- a
ij
=0, nếu ngược lại
i=1, 2,...,m, j=1, 2,...,n. Hãy bố trí các phòng họp cho các tiểu ban sao cho hội nghị kết thúc sau ít
ngày làm việc nhất.
Đưa vào các biến số :
x
ij
= 1, nếu bố trí tiểu ban i làm việc ở phòng j
x
ij
= 0, nếu ngược lại
i=1, 2,...,m ; j=1, 2,...,n, khi đó dễ thấy mô hình toán học cho bài toán đặt ra chính là bài toán (1)-
(2),
trong đó pi =1, i=1, 2,...,m.

III. Cơ sở thuật toán
Bổ đề 1:

Bài toán (1)-(2) có nghiệm tối ưu khi và chỉ khi:
Chứng minh:
Điều kiện cần
là hiển nhiên vì sự tồn tại phương án của bài toán suy ra bất đẳng thức trong (3) được
thực hiện ít nhất dưới dạng dấu đẳng thức.
Điều kiện đủ:
Chỉ cần chỉ ra rằng nếu có (3) thì luôn có phương án.
Giả sử (3) đúng, gọi:
Do (3) là điều kiện để (1)-(2) có nghiệm nên trong phần tiếp theo ta luôn giả thiết rằng điều kiện
được thực hiên.
Bây giờ ta chỉ ra rằng bài toán (1)-(2) có thể chuyển về giải một số hữu hạn bài toán luồng cực đại
trong mạng. Trước hết với mỗi k nguyên dương ta xây dựng mạng G
(k)
= (V,E) với
e thuộc E: khả năng thông qua c(e)
c(s,u
i
) = p
i

c(u
i
,v
j
) = a
ij


c(v
j
,t) = k
Bổ đề 2: Giả sử với k nào đó luồng cực đại trong mạng G
(k)
có giá trị Δ thì x* với x*
ij
= Φ (u
i
,v
j
) là
phương án của bài toán (1)-(2) trong đó Φ (u
i
,v
j
) là luồng qua (u
i
,v
j
)
Chứng minh:
Thật vậy, do luồng cực đại trong mạng có giá trị Δ và là nguyên nên Φ(s,u
i
) = p
i

Φ(u
i
,v

j
) thuộc {0,1} với i=1,2,...,m;j=1,2,...,n
Vậy x* là phương án của bài toán (1)-(2) (đpcm).
Bổ đề 3:
Giả sử x* là phương án tối ưu và k* là giá trị tối ưu của bài toán (1)-(2) thì luồng cực đại trong G
(k*)

có giá trị Δ
Chứng minh:
Do giá trị của luồng cực đại trong mạng G
(k*)
không vượt qu Δ, nên để chứng minh bổ
đề ta chỉ cần chỉ ra luồng với giá trị Δ trong mạng G
(k*)
.
Ta xây dựng luồng Φ như sau:
Dễ dàng chứng minh Φ là luồng trong mạng G
(m)
có giá trị Δ.(đpcm)
Bổ đề 4:
Nếu k=m thì luồng cực đại trong mạng G
(m)
có giá trị Δ.
Chứng minh:
Lập luận tương tự bổ đề 3 ta chỉ cần chỉ ra luồng với giá trị Δ trong mạng G
(m)
.
Thật vậy, giả sử x* là nghiệm bài toán (1)-(2) được xây dựng theo công thức như bổ đề 1, xây dựng
Φ theo bổ đề 3 ta có luồng giá trị Δ.(đpcm)
IV. Thuật toán:

Từ nhận xét 2 và 3 suy ra việc giải bài toán (1)-(2) là tìm k* nguyên dương nhỏ nhất sao cho luồng
cực đại trong mạng G
(k*)
có giá trị Δ. Nhận xét 4 giới hạn giá trị k* thuộc [1,m].
Từ đây rút ra thuật toán:
áp dụng phương pháp chia nhị phân trên đoạn [1,m] tìm k* trong mỗi bước
giải bài toán tìm luồng cực đại trong.
V. Chương trình
Input: file văn bản INPUT.TXT
- Dòng 1: Chứa 2 số m,n (m,n <= 100)
- Dòng 2: Chứa n số nguyên p
1
,p
2
,..,p
n
- Trong m dòng tiếp theo mô tả mảng a
Output: file văn bản OUTPUT.TXT
- Dòng 1 chứa giá trị tối ưu tìm được
- Các dòng sau mô tả mảng x
Chương trình:
Uses Crt;
Const
InputFile='Input.Txt';
OutputFile='Output.Txt';
Var
a,x:Array[1..100,1..100]of Integer;
TraceX,TraceY:Array[1..100]of Integer;
p:Array[1..100]of Integer;
Start,Finish,n,m,s,t,Delta,No:Integer;

fi,fo:Text;
Procedure Input;
Var
i,j:Integer;
Begin
Assign(fi,InputFile);
Reset(fi);
Readln(fi,m,n);
Delta:=0;
For i:=1 to m do
begin
read(fi,p[i]);
Delta:=Delta+p[i];
End;
For i:=1 to m do
For j:=1 to n do read(fi,a[i,j]);
Close(fi);
s:=m+1;
t:=n+1;
For i:=1 to m do a[s,i]:=p[i];
End;
Function FindPath:Boolean;
Var
Queue:Array[1..100]of Integer;
i,j,First,Last,v:Integer;
Begin
Fillchar(TraceX,Sizeof(TraceX),0);
Fillchar(TraceY,Sizeof(TraceY),0);
First:=1;
Last:=0;

For i:=1 to m do
If x[s,i]<a[s,i] then
begin
inc(last);
Queue[last]:=i;
traceX[i]:=-1;
end;
While First<=Last do
Begin
i:=Queue[First];
Inc(first);
For j:=1 to n do
If (traceY[j]=0)and(x[i,j]<a[i,j])then
begin
traceY[j]:=i;
If x[j,t]<a[j,t] then
begin
Finish:=j;
FindPath:=True;
Exit;

×