KPLANK - Bán dừa

Người Gửi: Dương Lee

  • Problem:

Nếu các bạn biết câu chuyện thương tâm "ăn dưa leo trả vàng" của Pirate hẳn đã phải khóc hết nước mắt khi anh ấy, vì lòng thương chim, đã bán rẻ trái dưa leo siêu bự của mình.  
Dưa leo cũng đã bị chim to lấy đi rồi, Pirate giờ chuyển sang nghề bán dừa để bù lỗ. Bất đắc dĩ thôi, vì trên đảo toàn là dừa...  
Nhưng mà bán cái gì thì đầu tiên cũng phải có biển hiệu đã. Pirate quyết định lùng sục trên đảo các mảnh ván còn sót lại của những con tàu đắm để ghép lại thành tấm biển. Cuối cùng anh cũng tìm được N tấm ván hình chữ nhật, tấm thứ i có chiều rộng là 1 đơn vị và chiều dài là ai đơn vị. Pirate dựng đứng chúng trên mặt đất và dán lại với nhau để được một mảnh ván to hơn (xem hình minh họa).
Việc cuối cùng chỉ là đem mảnh ván này đi cưa thành tấm biển thôi. Nhưng hóa ra đây lại là công việc khó khăn nhất. Pirate rất thích hình vuông và muốn tấm biển của mình càng to càng tốt, nhưng khổ nỗi trên đảo lại không có nhiều dụng cụ đo đạc. Không êke, không thước đo độ, nên Pirate chỉ còn cách dựa vào cạnh của N tấm ván ban đầu để cưa cho thẳng thôi. Pirate chỉ có thể cưa theo những đoạn thẳng chứa một cạnh nào đó (dọc hoặc ngang) của các tấm ván.  
Hãy giúp anh ấy cưa được tấm biển lớn nhất có thể.
Input
Dòng thứ nhất: ghi số nguyên N - số tấm ván. 
N dòng tiếp theo: mô tả độ cao của các tấm ván theo thứ tự trái sang phải sau khi đã dán lại.
Output
Một số nguyên duy nhất là độ dài cạnh của tấm biển lớn nhất có thể cưa được.
Độ cao của các tấm ván là các số nguyên dương không vượt quá 109.
1 ≤ N ≤ 106.
60% số test có 1 ≤ N ≤ 2000.
80% số test có 1 ≤ N ≤ 105.
Example:
Input
7
5
2
4
3
3
1
4
Output:
3

  • Solution:

- Giải thích: Hình dưới đây minh họa phương án tối ưu.
- Ý tưởng: + Áp dụng stack tại mỗi tấm ván tìm vị trí xa nhất bên trái mà tấm ván đó còn cắt được. + Áp dụng stack tại mỗi tấm ván tìm vị trí xa nhất bên phải mà tấm ván đó còn cắt được. - Thực hiện: + Đặt vị trí 0 và n+1 có độ cao là: 0 (hai điểm chốt hai đầu). + Duyệt 1: Duyệt từng phần tử i:(1->n) cho i (vị trí) vào stack. (trước khi cho vào stack thì pop hết tất cả các độ cao mà lớn hơn [i] - Điều này có nghĩa là loại các tấm ván cao hơn nó là các tấm ván có thể cắt được). Còn lại (top) chính là vị trí xa nhất không cắt được -> Lưu vị trí đó. + Duyệt 2: Tương tự nhưng duyệt (n->1). + Sau khi duyệt ta có left và right ở tại mỗi tấm ván.Vậy thì chỉ cần lấy left[]-right[]-1 là đã có chiều dài tối đa khi cắt theo tấm ván đó. -> Chỉ cần so sánh lấy max là được.

  • Code:

C++:



JAVA:


Share this

Related Posts

Previous
Next Post »