Tập QHĐ này gồm các phần : Phần 1: Một số kinh nghiệm khi làm QHĐ Phần 2: Một số bài toán QHĐ cơ bản Phần 3: Các bài luyện về QHĐ Phần 4: Hớng dẫn giải bài luyện QHĐ Các bài tập một số t
Trang 1Nhời nói đầu :
Quy hoạch động là một phơng pháp hữu hiệu để giải quyết một bài toán tối u Những bài giải bằng QHĐ đều cho kết quả tốt về cả đáp số lẫn thời gian Nhng để phát hiện ra và cài đặt tốt một bài quy hoạch động là rất khó khăn Thờng thì chúng ta hay tiếp cận với những bài toán QHĐ mà đọc lên đã có ngay dạng hay phơng pháp giải, nhng nh vậy là cha đủ bởi lẽ QHĐ không dừng lại ở đó Chúng
ta chỉ có thể giác ngộ t tởng để giải một bài QHĐ chứ chúng ta không thể học hết
đợc toàn bộ mọi phơng pháp quy hoạch tập bài này cũng vậy, có lẽ nó cũng chỉ cho ta biết và hình dung nho nhỏ về một số phuơng pháp QHĐ và những kinh nghiệm khi làm một bài toán quy hoạch mà tôi rút ra qua quá trình học tập v à giảng dạy Tập QHĐ này gồm các phần :
Phần 1: Một số kinh nghiệm khi làm QHĐ
Phần 2: Một số bài toán QHĐ cơ bản
Phần 3: Các bài luyện về QHĐ
Phần 4: Hớng dẫn giải bài luyện QHĐ
Các bài tập một số thuộc quá trình học tập giảng dạy của tôi và một số tuyển chọn
từ một số sách, tạp chí tin học Chắc chắn rằng tập bài này không thể hoàn thiện
và không tránh khỏi sai sót, xin đợc tiếp thu ý kiến đóng góp của các thầy, các cô.
Trang 2Phần 1 : một số kinh nghiệm khi làm quy hoạch động
QHĐ là một phơng pháp mạnh để giải các bài toán trong tin học QHĐ đòi hỏi một khả năng nhìn nhận và phân tích chi tiết một bài toán Để có đợc nhiều kinh nghiệm giải QHĐ thì không một cách nào khác là ta phải tiếp cận với càng nhiều càng tốt những bài toán QHĐ và theo tôi thì khuôn mẫu chung để làm quy hoạch động gồm ba bớc :
* Lập hệ thức : dựa vào nguyên lí tối u để chia bài toán thành giai đoạn làm việc Sau đó
tìm hệ thức biểu diễn quan hệ giữa các bớc đang xử lí với các bớc đã xử lí trớc đó hoặc tìm cách phân rã thành những bài toán con nhỏ hơn và từ đó xây dựng đợc phơng trình truy toán(dạng hàm hoặc thủ tục đệ quy)
* Tổ chức dữ liệu và chơng trình : tổ chức dữ liệu sao cho đạt yêu cầu sau:
+ dữ liệu đợc tính toán dần theo từng bớc
+ dữ liệu đợc lu trữ dể giảm lợng tính toán lặp lại
+ kích thớc miền nhớ dành cho lu trữ dữ liệu càng nhỏ càng tốt, kiểu dữ liệu đợc chọn phải phù hợp dễ truy cập
* Làm tốt : làm tốt bằng cách thu hẹp hệ thức và giảm không gian nhớ cần sử dụng.
Tuy lí thuyết quy hoạch động rất đơn giản nh vậy nhng việc áp dụng nó vào một bài toán là không hề dễ dàng bởi lẽ với mỗi bài toán đòi hỏi ta phải thiết lập đuợc một phơng trình truy toán khác nhau, chính phơng trình truy toán đó thể hiện khả năng t duy sáng tạo của mỗi ngời Nói chung quy hoạch động là một phơng pháp đòi hỏi ta phải nhìn nhận bài toán cực kì tinh tế và biết cách tổ chức dữ liệu hợp lí cộng với một phong cách lập trình tốt, không làm đợc vậy thì việc giải một bài quy hoạch động phức tạp là vô cùng khó khăn Trớc khi làm quy hoạch động hãy suy nghĩ thật kĩ để tìm ra và xây dựng công trức truy hồi cho thật chính xác và phải vạch ra đợc đờng lối làm việc đúng đắn và thông suốt, có vậy ta mới bắt tay vào lập trình, nếu không chỉ cần một lỗi nhỏ trong quá trình lập trình sẽ khiến ta phải tduy lại toàn bộ quá trình làm việc và cũng có thể bạn phải quay lại vị trí xuất phát và nh vậy
đơng nhiên bạn sẽ mất rất nhiều thời gian
Còn đây là cách nhìn nhận phơng pháp quy hoạch động của bạn Phạm Hải Minh
Quy hoạch động là một phương phỏp rất hay và mạnh của tin học Nhưng để giải được cỏc bài toỏn bằng phương phỏp quy hoạch động thật chẳng dễ dàng chỳt nào Chủ yếu học sinh hiện nay sử dụng quy hoạch động theo kiểu làm từng bài cho nhớ mẫu và ỏp dụng vào những bài cú dạng tương tự
Qua quỏ trỡnh học tập và giảng dạy tụi đó tự rỳt ra cho mỡnh một số kinh nghiệm về cỏch giải cỏc bài toỏn bằng quy hoạch động, xin đưa ra để mọi người cựng tham khảo và gúp
ý
1 Lớ thuyết:
Phương phỏp quy hoạch động gồm 6 bước:
- Bước 1: Chia nhỏ bài toỏn
Trang 3toỏn Ban đầu ta xõy dựng P với 1 thành phần duy nhất.
- Bước 2: Lập hệ thức quy hoạch động
Xõy dựng hàm f(P) là hàm tối ưu của vectơ P (hay hàm tối ưu cho mỗi bài toỏn con)f(P) = g(f(P1),f(P2), ,f(Pn))
g cú thể là hàm Max,Min hoặc tổng tuỳ yờu cầu của bài toỏn là tỡm Max,Min hay tớnh tổng
P gọi là vectơ cha
P1,P2,P3, ,Pn gọi là vectơ con
- Bước 3: Kiểm tra
Nếu khụng xõy dựng được hàm f thỡ thờm tiếp hoặc bỏ đi từng thành phần của vectơ P rồi quay lại bước 2 Nếu được thỡ làm tiếp bước 4
- Bước 4: Tối ưu hoỏ hệ thức
Tối ưu vectơ P bằng cỏch xột từng thành phần x của vectơ P:
Chọn vectơ PBest trong P1,P2,P3, Pn chỉ khỏc nhau thành phần x sao cho cú thể đưa PBest vào thay P1,P2,P3 ,Pn trong hàm g mà khụng làm thay đổi giỏ trị của hàm g thỡ cú thể đơn giản thành phần x của vectơ P
- Bước 5: Chọn kiểu quy hoạch động
+ Kiểu 1: Nếu cỏc thành phần của vectơ con P1 luụn ≤ hay ≥ cỏc thành phần của vectơ cha P thỡ ta cú thể dựng cỏc vũng lặp for lồng nhau để cài đặt
+ Kiểu 2: Nếu vectơ P và vectơ P1 luụn cú mối quan hệ cha con một chiều thỡ ta cú thể dựng phương phỏp đệ quy cú nhớ để cài đặt
+ Kiểu 3: Nếu vectơ P và vectơ P1 luụn cú mối quan hệ cha con hai chiều nhưng khụng
rừ đõu là vectơ cha , đõu là vectơ con vỡ cũn phụ thuộc vào từng bài toỏn thỡ ta cú thể dựng phương phỏp repeat until để cài đặt
- Bước 6: Tối ưu hoỏ bộ nhớ (chỉ dựng cho cài đặt kiểu 1)
Đơn giản vectơ P bằng cỏch xột từng thành phần x của vectơ P:
Nếu f(P( ,x, ))=g(f(P1( ,x1, )),f(P2( ,x2, )), ,f(Pn( ,xn, )))
và x-x1, x-x2, , x-xn≤T nào đú thỡ ta chỉ cần đưa vũng lặp của x lờn đầu tiờn và bỏ x ra khỏi vectơ P và lưu T+1 vectơ P
Tóm lại dù nói thể nào thì phơng pháp này chủ yếu đòi hỏi khả năng thiết lập một phơng
án chia nhỏ và phân rã bài toán cho tới khi vấn đề còn lại ta có thể giải quyết ngay tức thì
Phần 2 : Một số bài toán quy hoach động cơ bản:
Trang 4Bài1 : Dãy con tăng dài nhất : Cho dãy số nguyên n phần tử, hãy tìm dãy con tăng chặt dài nhất của
dãy đã cho ( các phần tử của dãy con có thể không liên tiếp nhau)
Dữ liệu vào file DCT.INP:
- dòng đầu tiên ghi số n (1<=n<=10000)
- dòng thứ i trong số n dong tiếp theo mỗi dòng ghi số ai (0<=ai<=30000)
Kết quả ra file DCT.OUT dòng đầu tiên ghi m là số lợng phần tử của dãy con tăng dài nhất tìm
đ-ợc m dong sau mỗi dòng ghi một phần tử của dãy con tăng tìm đđ-ợc
Giải thuật : Gọi dãy ban đầu là a1,a2, an đặt D[i] là độ dài lớn nhất của dãy con tìm đợc từ dãy bắt
đầu từ vị trí a1 kết thúc ở ai nh vậy ta có hệ thức quy hoạch động : D[i]= Max(D[j]+1) (với
Trang 5For j:=i-1 downto 0 do
if (a[i]>a[j]) and (D[i]<D[j]+1) then
Trang 7Dữ liệu vào file valy.inp dong đầu tiên là số N và W, dòng thứ i trong số N dòng tiếp theo mỗi dòng ghi hai số A[i] và C[i]
Kết quả ra : file valy.out theo quy cách sau
dòng đầu tiên là tổng giá trị lớn nhất tìm đợc của valy
các dòng tiếp theo mỗi dòng ghi hai số i (là số hiệu vật đợc chọn) x (là số lợng chọn vật i)
hớng dẫn : dùng mảng một chiều gọi D[i] là tổng giá trị lớn nhất khi thể tích là i, nh vậy
D[i]=Max(D[i-A[j]] + C[j]) với mọi 1<=j<=n 1<=i<=W
kết quả là giá trị lớn nhất trong mảng D ta xây dựng một mảng chọn với Chon[i] 1<=i<=W là giá trị tối u trong phơng án chọn ở i và vật đợc chọn cuối cùng là Chon[i] Chơng Trình nh sau:
Type m1 = array [1 maxN] of integer;
m2 = array [0 maxW] of longint;
m3 = array [0 maxW] of integer;
Trang 8Kết quả ra : file valy.out theo quy cách sau
dòng đầu tiên là tổng giá trị lớn nhất tìm đợc của valy
các dòng sau mỗi dòng ghi một số là số hiệu của vật đợc chọn.
Hớng dẫn : * tổ chức dữ liệu : Mảng hai chiều L(N,W) : L[i,j] là giá trị tối u của valy khi trọng lợng max là j
và xét các vật từ 1 >i
Trang 10Bài 4 : Bài toán chia kẹo
Cho n gói kẹo gói thứ i có A[i] cái kẹo.Yêu cầu hãy tìm cách chia các gói kẹo này thành hai phần sao cho độ chênh lệch giữa tổng số kẹo ở hai phần là nhỏ nhất có thể
Dữ liệu vào : file chiakeo.inp dòng đầu là số n
dòng thứ i trong số n dòng tiếp theo mỗi dòng ghi số A[i] là số kẹo có trong gói thứ i
(n<=100 và A[i]<=200)
kết quả : file chiakeo.out dòng đầu tiên là độ chênh lệch min
các dong sau ghi ra số hiệu các gói kẹo của một phần trong cách chia tìm đợc
Hớng dẫn : để tìm cách chia các gói kẹo thành hai phần chênh lệch min thì cần chia sao cho tổng
số kẹo trong một phần gần với giá trị (Tong div 2) nhất, trong đó tong là tổng số kẹo của tất cả n gói Phơng án quy hoạch của ta ở đây là tìm ra một số các gói kẹo sao cho tổng số kẹo của nó gần (tong div 2) nhất Để làm đợc vậy ta dùng một mảng D là mảng một chiều và ta quy hoạch trên mảng ấy với quy ớc D[i]=0 thì không có phơng án chọn ra trong số n gói kẹo một số gói để tổng số kẹo trong các gói đợc chọn là i
còn D[i]<>0 thì có phơng án chọn ra một số gói kẹo sao cho tổng số kẹo các gói đợc chọn là i và gói cuối cùng đợc chọn là D[i] nh vậy ta cần tìm một giá trị D[i]<>0 sao cho i lớn nhất và không v-
ợt quá (tong div 2)
Để làm đợc vậy ban đầu ta chuẩn bị một mảng D array[0 Tong div 2]
Trang 11ở đây n<=100 a[i]<=200 nên Tong<=20000 vậy kích thớc tối đa của mảng D là 10000 ban đầu ta cho D[0] nhận một giá trị khác 0 vì ban đầu ta khởi tạo cha chọn gói kẹo nào, các giá trị còn lại của mảng D ta gán giá trị 0.
ta lần lợt xét từng gói kẹo từ 1 > n giả sử khi xét đến gói thứ i ta sẽ tìm xem nếu có thêm gói kẹo thứ i thì nó có thể thành lập đợc thêm những tổng nào cha đợc thành lập khi xét đến gói kẹo thứ i-1
và cứ nh vậy khi xét đến gói thứ n thì ta có đợc tất cả các cách chia khác nhau Ta làm nh sau
Fillchar(D,sizeof(D),0);
D[0]:=1;
For i:=1 to n do
For j:=Tong Div 2 downto A[i] do
If (D[j]=0) and (D[j-A[i]]<>0 ) then
Type m1 = array [1 maxn] of byte;
m2 = array [0 maxT] of byte;
Trang 12procedure qhoach;
var i,j:integer;
begin
for i:=n downto 1 do
for j:=dich downto a[i] do
if (d[j]=0) and (d[j-a[i]]<>0) then
Bài 5 : di chuyển từ tây sang đông
Cho ma trận M*N mỗi ô chứa một số nguyên ta cần di chuyển từ một ô bất kì thuộc cột bên trái sang một ô bất kì thuộc cột bên phải Mỗi bớc di chuyển từ một ô (i,j) ta có thể đi sang ô (i-1,j+1) hoặc (i,j+1) hoặc (i+1,j+1) Chi phí cho một đờng đi là tổng của các số nguyên trên con đờng đó Yêu cầu hãy tìm ra một con đờng đi với chi phí thấp nhất
Dữ liệu vào : file Taydong.inp dòng đầu là số m , n
dòng thứ i trong số m dòng tiếp theo chứa n số nguyên trong phạm vi (-1000 1000) (m,n<=100)Kết quả ra : file Taydong.out dòng đầu ghi một nguyên là chi phí min tìm đợc
n dòng tiếp theo ghi chỉ số của hàng lần lợt di chuyển từ tây sang đông
Trang 13Hớng dẫn : theo cách di chuyển nh vậy ta nhận thấy tới ô (i,j) có thể đi từ ô (i-1,j-1) (i,j-1) (i+1,j-1)
và nh vậy ta quy hoạch nh sau
Dùng C là bảng 2 chiều M*N và C[i,j] là chi phí min để di chuyển từ cột trái tới ô (i,j) nh vậy chi phí min để di chuyển từ tây >đông là giá trị nhỏ nhất của cột thứ n trong mảng C
Trang 14if T = a[i-1,j+1] then Dec(i)
else if T = a[i+1,j+1] then Inc(i)
Bài 6 : Rút bài ( cách diễn đạt khác của bài nhân ma trận)
Cho n lá bài xếp trên bàn và đánh số từ 1 tới n mỗi lá mang một số nguyên dơng theo đúng thứ tự đã xếp là a1,a2, ,an Mỗi lần ta đợc phép rút một lá bài ra khỏi dãy bài đang xếp và chi phí để rút lá bài thứ i trong dãy là tích của ba số nguyên là ba số nghi trên lá bài rút ra và hai lá bài đặt cạnh nó ở thời
điểm hiện tại
(lu ý : với cách tính chi phí nh vậy thì ta không rút hai lá bài ở hai đầu Mỗi lần rút thì tập bài sẽ thu hẹp lại một lá và nh vậy có sự thay đổi về vị trí bên cạnh của hai lá bài cạnh lá vừa rút)
Yêu cầu : hãy rút đi n-2 lá bài với chi phí nhỏ nhất Bạn hãy tìm và in ra cách rút đó
Dữ liệu vào : file card.inp dòng đầu tiên là số n dòng thứ i trong n dòng tiếp theo mỗi dòng ghi số nguyên ai (n<=100 ai<=100)
Kết quả ra : file card.out dòng đầu tiên ghi chi phí min để rút n-2 lá bài dòng thứ i trong số n-2 dòng tiếp theo bài ghi chỉ số của lá bài đợc rút theo số hiệu ban đầu
Hớng dẫn : dùng mảng hai chiều C[i,j] có ý nghĩa là chi phí tối thiểu để rút hết các lá bài thuộc đoạn
[i,j] theo thứ tự ban đầu, nh vậy C[i,j] đợc tính từ các giá trị C[i,k-1] và C[k+1,j] ( i=<k<=j)
C[i,j]=Min(C[i,k-1]+C[k+1,j]+Chiphí(Rút lá bài k khi đã rút hết các đoạn [i,k-1] và [k+1,j]))
k đợc hiểu là lá bài cuối cùng đợc rút trong đoạn [i,j] trong phép rút tối u
Trang 15Phần 3 : một số bài luyện quy hoạch động
Trang 16Bài toán 1 :ngân hàng trả tiền
Một người đi lấy tiền ở một ngân hàng Anh ta cần lấy một khoản đúng M đồng Ngân hàng có N đồng tiền A1, A2, , AN Hỏi ngân hàng có bao nhiêu cách trả tiền
Dữ liệu vào trong file: "MONEY.INP" có dạng:
+ Dòng đầu là hai số N và M (N <=100, M <= 10000)
+ Các dòng tiếp theo là các phần tử của mảng A
Kết quả ra file: "MONEY.OUT" gồm một dòng duy nhất là số cách trả tiền (Số cách trả tiền < Maxlongint)
Bài toán 2 : Dãy có tổng chia hết cho k (đề thi toàn Quốc)
Cho một dãy số nguyên A1, A2, , AN và một số k Hãy tìm một dãy con (không nhất thiết phải liên tiếp nhau) dài nhất có tổng các số chia hết cho số k
Dữ liệu vào trong file "dayso.inp" có dạng:
+ Dòng 1 gồm 2 số N và k (N<=1000; k<=50)
+ Các dòng tiếp theo chứa các số của mảng A
Kết quả ra file "dayso.out" gồm một dòng ghi số phần tử lớn nhất tìm được.
6 5
1 2 7 3 4 5
5
Bài toán 3 : mua bán hàng
Có một người đi mua hàng, anh ta có N đồng tiền d1, d2, , dN Người bán hàng có M đồng tiền b1, b2, , bm Anh ta muốn mua một mặt hàng với giá trị W Hỏi cuộc mua bán có thể diễn ra được không?
Giới hạn: M, N<=100 và d i , b j <=100.
Bài toán 4 : xoay DOMINO
Cho N thanh DOMINO xếp theo chiều dọc như hình vẽ
Ví dụ hình trên gồm 5 thanh DOMINO
Trang 17Mỗi thanh DOMINO gồm 2 phần, phần trên và phần dưới Trên mỗi phần có một số từ 1 đến 6 Yêu cầu đặt ra là hãy tìm cách xoay các thanh (xoay 180 độ) để sau khi xoay chênh lệch giữa tổng trên và tổng dưới là ít nhất.
Giới hạn: N<=1000.
Bài toán 5 : Giá trị biểu thức
Giả thiết X,Y là hai số nguyên dương Kí hiệu Sx là tổng các chữ số trong dạng biểu diễn cơ số 10 của X, Dmax_y là chữ số lớn nhất và Dmin_y là chữ số nhỏ nhất trong dạng biểu diễn cơ số 10 của
Y Phép tính hai ngôi # với các toán hạng nguyên dương X,Y được định nghĩa như sau:
( X#Y ) = Sx*Dmax_y + Dmin_y
Ký hiệu kết quả biểu thức là K Cho X và K (0 < X,K < 109-1) cần xác định số ít nhất m các phép #
để từ đó có thể xây dựng biểu thức thuộc dạng đang xét với X cho kết quả K và biểu diễn của biểu thức
Dữ liệu vào từ file văn bản BT.IN, dòng thứ nhất chứa X, dòng thứ hai chứa K
Kết quả ra file văn bản BT.OUT, dòng thứ nhất chứa m, dòng thứ hai chứa biểu thức
Ví dụ:
71881
3((718 #(718 #718)) #718)
Bài toán 6 : Lịch thuê nhân công
Có một dự án kéo dài trong T tháng và người quản lý cần phải lập lịch sử dụng công nhân trong dự
án, anh ta biết số công nhân tối thiểu cần trong mỗi tháng Mỗi khi thuê hay sa thải một công nhân thì đều phải mất một chi phí xác định, mỗi công nhân được thuê sẽ vẫn nhận được lương tháng ngay cả khi không sử dụng anh ta làm việc
Với mỗi công nhân, người quản lý biết chi phí thuê, chi phí sa thải và tiền lương phải trả cho công nhân đó trong 1 tháng Và bài toán đặt ra như sau: Cần phải thuê hay sa thải bao nhiêu công nhân mỗi tháng để tổng chi phí dành cho nhân công của dự án là nhỏ nhất, tức là giảm tối đa chi phí của
dự án
Trang 18Dữ liệu vào từ file văn bản EMPLOY.IN có cấu trúc như sau:
- Dòng đầu ghi T là số tháng diễn ra dự án (T=<100)
- Dòng thứ hai ghi 3 số lần lượt là chi phí thuê, lương tháng, chi phí sa thải mỗi công nhân
- Dòng cuối cùng là T số nguyên dương, số thứ i cho biết số công nhân tối thiểu cần cho tháng thứ
i, các giá trị số không quá 150
Kết quả ra file văn bản EMPLOY.OUT theo định dạng:
- Dòng thứ nhất ghi tổng chi phí nhỏ nhất tìm được
- Dòng thứ hai ghi T số, số thứ i là số công nhân hoạt động trong dự án tại tháng thứ i
Ví dụ về file dữ liệu vào và file kết quả ra:
Bài toán 7 :Tiền kim loại
Giả sử tại một lúc nào đó bạn có N loại tiền kim loại (dạng đồng xu) được đánh số từ 1 đến N, mỗi
loại có số lượng đồng không giới hạn Mỗi đồng của loại tiền kim loại thứ i mang giá trị vi xu và có trọng lượng là wi gam Vì các loại tiền được đúc bằng các kim loại khác nhau nên có thể có những
loại tiền cùng giá trị hoặc cùng trọng lượng nhưng không thể đồng thời có cả cùng giá trị và trọng lượng
Trong số N loại tiền của bạn, hãy chọn ra một số ít nhất M các đồng sao cho chúng có tổng giá trị
là V xu và tổng trọng lượng là W gam M sẽ nhận giá trị 0 nếu không có cách chọn các đồng tiền thoả mãn hai giá trị V và W
Ví dụ 1: Cho thông tin về N=8 đồng tiền như sau:
i vi wi
Trang 19Dữ liệu vào từ file COIN.IN có cấu trúc:
- Dòng đầu chứa 3 số tự nhiên N, V, W (1<=N<=20; 1<=V,W<=150)
- N dòng tiếp theo, dòng thứ i chứa cặp số (vi,wi) là thông tin về một đồng của loại tiền thứ i
(1<=vi, wi<=150)
Kết quả ghi ra file COIN.OUT giá trị M thoả mãn yêu cầu đặt ra, ghi M=0 nếu không tìm được cách thoả mãn
trọng lượng là W, và trong M đồng này có một đồng loại i, thế thì với tổng giá trị V-vi, tổng Ví dụ
về file dữ liệu vào và file kết quả ra:
Bài toán này không phải là một bài khó và dễ dàng hơn nếu ta đánh giá rằng: giả sử có trong tay số
ít nhất M đồng tiền để tổng giá trị là V, tổng trọng lượng W-wi chắc chắn cần số ít nhất là M-1 đồng tiền, i=1 N Nhận xét này cho thấy công thức truy hồi nếu muốn tính M Xét mảng Coin[1 150,1 150], Coin[i,j] cho biết số tối thiểu đồng tiền thỏa mãn điều kiện số đồng tiền này có tổng giá trị là i, tổng trọng lượng là j, (i=1 V, j=1 W) thế thì:
Coin[i,j] = Min{Coin[i-v[k], j-w[k]] +1}
Bài toán 8 : Xoay ô
Cho một lưới ô vuông kích thước M´N (M<= 50, N<= 8) Mỗi ô vuông được chia thành 4 miền bằng hai đường chéo, mỗi miền được tô đen hoặc trắng Với bất cứ một ô nào, có thể lấy giao điểm hai đường chéo của ô đó làm tâm và xoay ô đó đi một góc 900, 1800 hoặc 2700
Trang 20Từ một bảng ban đầu, người ta muốn xoay cỏc ụ sao cho hai miền chung cạnh phải cú cựng màu Tất nhiờn là cú nhiều cỏch xoay cỏc ụ để đạt được mong muốn nhưng yờu cầu đặt ra là tỡm một cỏch xoay cỏc ụ sao cho tổng số ụ phải thực hiện phộp xoay là nhỏ nhất cú thể được
Dữ liệu vào từ file văn bản XOAY.IN bao gồm:
xij1: miền trờn
xij2: miền trỏi
xij3: miền dưới
xij4: miền phải
Kết quả ra file XOAY.OUT thể hiện:
- Nếu khụng cú cỏch xoay thỡ ghi số 0
- Nếu tồn tại nghiệm thỡ dũng đầu tiờn ghi tổng số phộp xoay, tiếp theo là M dũng, mỗi dũng N bộ
số cho biết tỡnh trạng của bảng sau khi thực hiện cỏc phộp xoay
Vớ dụ về file dữ liệu vào và file kết quả ra:
Bài toán 9 : cho dãy n phần tử nguyên a1,a2 an Một phép rút gọn dãy làm cho dãy giảm đi một
phần tử, phép rút gọn dãy tại vị trí thứ i nh sau : + gán a(i) cho a(i)-a(i+1)
+ loại bỏ a(i+1) ra khỏi dãy
+ đẩy đoạn (i+2) đến (n) thành đoạn (i+1)
đến (n-1) Nh vậy sau mỗi phép rút gọn dãy giảm đi một phần tử
Yêu cầu : hãy tìm ra thứ tự rút gọn sao cho sau n-1 phép rút gọn dãy còn lại một phần tử và nó nhận giá trị T
Dữ liệu vào : file RG.inp dòng đầu là n và T
dòng thứ i trong số n dòng tiếp theo ghi số ai
Kết quả ra : file RG.out dòng đầu là 0 hoặc 1 thể hiện có hay không phơng án rút gọn để đạt kq T Nếu dòng đầu là 1 thì n-1 dòng tiếp theo ghi mỗi dòng một phép rút gọn theo đúng thứ tự đã thực hiện để đạt đợc kết quả T
Bài toỏn 10: Palindrome (time limit 2s)
Một xõu được gọi là xõu đối gương nếu đọc từ trỏi qua phải cũng giống như đọc từ phải qua trỏi Vớ
dụ xõu "madam" là một xõu đối gương Bài toỏn đặt ra là cho một xõu S gồm cỏc kớ tự thuộc tập M=[’a’ ’z’], hóy tỡm cỏch chốn vào xõu S cỏc kớ tự thuộc tập M tại cỏc vị trớ bất kỡ với số lượng kớ
tự chốn vào là ớt nhất để xõu S thành xõu đối gương Vớ dụ: xõu: "adbhbca" ta sẽ chốn thờm 2 kớ tự (
c và d) để được xõu đối gương "adcbhbcda"
Dữ liệu vào trong file PALIN.IN cú dạng:
Dũng thứ nhất là một số nguyờn dương T (T <=10) là số bộ test
T dũng sau, mỗi dũng chứa một xõu S, độ dài mỗi xõu khụng vượt quỏ 500
Kết quả ghi ra file PALIN.OUT cú dạng: Gồm nhiều dũng, mỗi dũng là một xõu đối gương sau khi
đó chốn thờm ớt kớ tự nhất vào xõu S tương ứng ở file input
palin.inp palin.out
Trang 21Bài toán 11: Có N người sắp hàng mua vé dự buổi hoà nhạc Ta đánh số họ từ 1 đến n theo thứ tự
đứng trong hàng Mỗi người cần mua một vé, song người bán vé được phép bán cho mỗi người tối
đa 2 vé Vì thế một số người có thể rời hàng và nhờ người đứng trước mình mua hộ vé Biết ti là thời gian cần thiết để người i mua xong vé cho mình Nếu người i+1 rời khỏi hàng và nhờ người i mua hộ vé thì thời gian để người thứ i mua được vé cho cả hai người là ri
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 vé để
tổng thời gian phục vụ bán vé là nhỏ nhất
Dữ liệu: Vào từ file TICK.INP
- Dòng đầu tiên chứa số n (1<N<2001)
- Dòng thứ 2 ghi N số nguyên dương t1, t2, ,tn
- Dòng thứ 3 ghi N-1 số nguyên dương r1, r2, ,rn-1
Kết quả: Ghi ra file văn bản TICK.OUT
- Dòng đầu tiên ghi tổng số thời gian phục vụ
- Dòng tiếp theo ghi chỉ số của các khách hàng cần rời khỏi hàng (nếu không có ai cần rời khỏi hàng thì quy ước ghi một số 0)
Ba bạn Kiên, Hùng, Thành chơi rất thân với nhau, bạn Hùng học chuyên Toán còn hai bạn Thành
và Kiên học lớp chuyên Tin Một lần, bạn Hùng mang ra N khối đá ( N ≤ 5000 ), các khối đá đều
có dạng hình hộp chữ nhật và được đặc trưng bởi 3 kích thước Một cách xây tháp là cách đặt một
số khối đá trong các khối đã cho chồng lên nhau theo quy tắc:
- Chiều cao của mỗi khối đá là kích thước nhỏ nhất trong 3 kích thước
- Các mép của các khối được đặt song song với nhau sao cho không có phần nào của khối trên nằm chìa ra ngoài khối dưới
Trong lúc các bạn còn đang ngạc nhiên, Hùng nói:
'Bây giờ, từ N khối đá này, Thành hãy giúp tớ xây được một cái tháp để số các khối đá còn lại sau khi xây là ít nhất Còn Kiên, cậu chờ Thành làm xong rồi xây cho tớ cái tháp có chiều cao lớn nhất cũng từ N khối đá này nhé! Được không!'
Thành và Kiên cười : 'Chuyện nhỏ! Cái món này thì đúng sở trường của dân Tin bọn anh rồi chú
em ạ! Hùng khoanh tay: 'Thì cứ thử xem ! Và ngay lập tức, Kiên và Thành bắt tay vào làm
Còn bạn, bạn còn chờ gì nữa mà không thử sức với bài toán tin này
Dữ liệu vào: Hung.inp ghi thông tin về các khối đá mà Hùng đem ra:
- Dòng đầu là số N
- N dòng sau, dòng thứ i ghi 3 số nguyên dương không quá 255 là kích thước của khối đá thứ i
Dữ liệu ra: Kien.out ghi cách xếp tương ứng với câu Hùng hỏi Kiên:
- Dòng đầu là số khối đá của tháp
- Các dòng sau mỗi dòng ghi các khối đá theo thứ tự từ đáy tháp lên đỉnh tháp, mỗi dòng một số theo thứ tự là: T, D, R, C, trong đó T là số hiệu khối đá, D là chiều dài, R là chiều rộng và C là chiều cao của khối đá tương ứng
Thanh.out ghi cách xếp tương ứng với câu Hùng hỏi Thành theo quy cách giống như trên
Trang 22Với mọi bộ dữ liệu thoả mãn, chương trình của bạn không được chạy quá 5 giây và nếu dưới 3 giây thì càng tuyệt vời (đặt {$R-})
Bài toán 13: Một đại lý kinh doanh xăng dầu có n trạm bán xăng dầu (gọi tắt là cây xăng) đánh số
từ 1 đến n trên một đường cao tốc muốn tìm vị trí đặt k bể chứa xăng để cung ứng xăng cho các cây xăng Trên đường cao tốc người ta đặt các cột mốc cây số, bắt đầu từ cột số 0 Biết vị trí của cây xăng thứ i là ở cột cây số di (i=1,2, ,n): d1 < d2 < n
Yêu cầu: Tìm vị trí đặt k bể chứa xăng tại k trong số n cây xăng sao cho khoảng cách lớn nhất từ
cây xăng không có bể chứa đến cây xăng có bể chứa gần nó nhất là nhỏ nhất
Dữ liệu: Vào từ file văn bản VITRI.INP
- Dòng đầu tiên ghi 2 số nguyên dương n, k (n<200, k<30,k
- Dòng thứ 2 ghi các số d1, d2, ,dn (di là các số nguyên dương không quá 320000) Các số trên cùng một dòng ghi cách nhau ít nhất một dấu trắng
Kết quả: Ghi ra file văn bản VITRI.OUT
File gồm k dòng, mỗi dòng ghi chỉ số cây xăng đặt bể chứa xăng
Bài toán 14
Cho n bức tranh mã số từ 1 n (n<=50) Người ta cần chọn ra một bức để đặt ở cửa phòng tranh, số còn lại được treo thẳng hàng trong phòng trên m vị trí định sẵn có mã số 1 m từ trái qua phải Các bức tranh phải được treo theo trật tự nghiêm ngặt sau đây: tranh có số hiệu nhỏ phải treo ở trên tranh có số hiệu lớn
Trang 23- Tranh thứ i treo tại cửa sẽ đạt trị thẩm mỹ c[i];
- Tranh thứ i treo tại vị trí j sẽ đạt trị thẩm mỹ v[i,j]
- m+1≥n
- Các giá trị thẩm mỹ là những số tự nhiên không vượt quá 50
Yêu cầu: Hãy xác định một phương án treo tranh để có tổng trị thẩm mỹ là lớn nhất
Dữ liệu vào: Tệp văn bản 'Picture.INP'
- Dòng thứ nhất ghi n, m (cách nhau 1 dấu cách)
- Dòng tiếp theo là n giá trị c
- Tiếp đến là n dòng, dòng i gồm m vị trí v[i,1], v[i,2], v[i,m]
Dữ liệu ra: Tệp văn bản ' Picture.OUT'
- Dòng thứ nhất ghi giá trị thẩm mỹ lớn nhất tìm được
- Dòng thứ hai: ghi mã số hiệu bức tranh treo ở cửa phòng tranh
- Dòng thứ 3 ghi n-1 số tự nhiên sắp tăng chặt cho biết mã số các vị trí được chọn để treo tranh picture.inp picture.out
Bài toán 15 Có một số quân cờ nhảy, mỗi quân được sơn một trong số K màu khác nhau (K ≤ 25)
Trên mỗi quân cờ ghi một số nguyên không âm bằng một trong số N số nguyên không âm cho trước (N ≤ 101) K quân cờ có màu khác nhau từng đôi một tạo thành một bộ cờ Hai bộ cờ gọi là giống nhau, nếu số ghi trên các quân cờ cùng màu là như nhau Trong trường hợp ngược lại hai bộ
cờ gọi là khác nhau Tổng các số ghi trên các quân của một bộ cờ gọi là trọng số của nó
Yêu cầu: Hãy tìm số bộ cờ khác nhau có cùng trọng số S (0 < S ≤ 300)
Dữ liệu: Vào từ file văn bản COMPLETE.INP:
Dòng đầu tiên chứa số nguyên K,
Kết quả: Đưa ra file văn bản COMPLETE.OUT số lượng tìm được (nguyên)
Bài toán 16 Giám đốc một công ty trách nhiệm hữu hạn muốn xin chữ kí của ông kiến trúc sư
trưởng thành phố phê duyệt dự án xây dựng trụ sở làm việc của công ty Ông kiến trúc sư trưởng chỉ ký vào giấy phép khi bà thư ký của ông ta đã ký duyệt vào giấy phép Bà thư kí làm việc tại tầng thứ M của một toà nhà được đánh số từ 1 đến M, từ thấp lên cao Mỗi tầng của toà nhà có N phòng được đánh số từ 1 đến N, từ trái sang phải Trong mỗi phòng chỉ có 1 nhân viên làm việc Giấy phép của bà thư kí ký duyệt khi có ít nhất một nhân viên ở mỗi tầng của toà nhà đã kí xác
Trang 24nhận Một nhân viên bất kỳ có thể chỉ kí xác nhận vào giấy phép khi có ít nhất một trong các điều kiện sau được thoả mãn:
* Nhân viên đó làm việc ở tầng 1
* Giấy phép đã được kí xác nhận bởi một nhân viên làm việc ở phòng liền kề (hai phòng được gọi
là liền kề khi chỉ số phòng sai khác nhau một đơn vị)
* Giấy phép được kí xác nhận bởi nhân viên làm việc ở phòng cùng số phòng ở tầng dưới
Mỗi nhân viên khi đã kí xác nhận đều phải có một chi phí nhất định Hãy chỉ ra cách xin chữ kí sao cho xin được chữ kí của ông kiến trúc sư trưởng mà chi phí bỏ ra là ít nhất
Dữ liệu:
Vào từ file Sign.Inp như sau:
* Dòng đầu tiên ghi M, N (1 <= M <= 100; 1 <= N <= 500);
* Dòng thứ i trong số M dòng tiếp theo ghi N số biểu diễn chi phí phải trả khi kí ở các phòng của tầng i Các số cách nhau bởi một dấu cách
Kết quả:
Ghi ra file: Sign.Out như sau:
* Dòng đầu tiên ghi hai số F, K theo thứ tự là chi phí cần trả và số lượng phòng cần đi qua
* K dòng tiếp theo ghi thông tin của các phòng theo thứ tự cần đi qua, mỗi dòng ghi 2 số là số thứ
Dữ liệu vào: từ file văn bản BSCNN.INP: là 1 số N
Kết quả: Ghi ra file văn bản BSCNN.OUT, bao gồm 2 dòng, dòng thứ nhất ghi giá trị số Max tìm được Dòng thứ hai ghi n bộ số a1,a2,, , ak tương ứng, các số cách nhau bằng dấu cách
Ví dụ
bscnn.inp bscnn.out
3 3 4 5 7