超大鏡框設置
TIOJ1370 解題報告
題意概要
給定一個每段高度不一的鏡框,問最大能
擺下面積為多少的鏡子。
一個比較慢的方法
枚舉矩形的左右界,再找出其中最低高度
。
依此類推,即得答案。
……
但是
這樣好像有點慢,左右界的對數有
n*(n-1)/2 組,再算上對每一組找最低高
… 度的時間
好像有點慢囧 rz
一個簡單的觀察
最大的矩形一定頂天立地 ( 四邊都有碰到
框框 ) ,否則矩形可以再擴張。
……
所以
我們得到了一個似乎快一點的方法:
對於每個左界,我們只找無法再往右的右 界 ( 再往右會造成最低的高度降低 )
對於這個紅色的左界 候選的右界只有一個
……
但是
雖然我們盡量將可能的組數降低了,而且 不必花費額外的時間查找中間最低的高度
,但是仍需要檢查所有的 n*(n-1) 組組合
,以找到適合的組合。
好像還是有點慢囧 rz
再一次觀察
再讓我們觀察一下,許多的左界似乎擁有 相同的右界。
對於這兩條紅色的左界候選的右界中,
都共同有最右邊的一條右界
……
所以
其實對於很多左界,我們是可以不用一一 找右界的!
經由上述觀察,我們得到了一個新方法!
利用 stack 的新方法
另 stack 的每個元素中,紀錄水平位置及高度
由左到右依序將每一格 push 進 stack 中,再加 入前不斷 pop 裡頭的元素,直到新的元素加進 去後,高度會在 stack 中維持遞增。
利用 stack 的新方法
在 pop 的同時,以 pop 出的元素為左界,即將 push 的元素為右界,且因為原 stack 中高度為 遞增關係,所以高度必為即將 pop 出的元素代 表的高度,每次 pop 皆檢查以該方式產生的矩 形是否會比已知的更大。
但需要注意的是,若 push 前曾經 pop 過元素,
代表在自己以前有元素比自己高,因此左界尚 可往左移, push 的元素需要更動水平位置。
利用 stack 的新方法
(1,1)
(2,2)
(3,3)
(4,2)
(5,4)
(6,2)
目前矩形最大面積: 0 將 (1,1)push 進 stack 中
(1,1)
(7,0)
利用 stack 的新方法
(2,2)
(3,3)
(4,2)
(5,4)
(6,2)
目前矩形最大面積: 0 因為 2>=1 ,
所以將 (2,2)push 進 stack 中
(1,1) (2,2)
(7,0)
利用 stack 的新方法
(3,3)
(4,2)
(5,4)
(6,2)
目前矩形最大面積: 0 因為 3>=2 ,
所以將 (3,3)push 進 stack 中
(1,1) (2,2) (3,3)
(7,0)
利用 stack 的新方法
(4,2)
(5,4)
(6,2)
目前矩形最大面積: 0
因為 2<3 ,
所以將 (3,3)pop 出來 並更新面積
(4-3)*3=3
(1,1) (2,2) (3,3) 3
(7,0)
利用 stack 的新方法
(4,2)
(5,4)
(6,2)
目前矩形最大面積:
(1,1) (2,2) 3 因為 2>=2 ,
且上一個 stack 中 pop 掉的 (3,3) 高於自己,所以將左界改成 3
將 (3,2)push 進 stack 中
(3,2)
(7,0)
利用 stack 的新方法
(5,4)
(6,2)
目前矩形最大面積: 3 因為 4>=2 ,
所以將 (5,4)push 進 stack 中
(1,1) (2,2) (3,2)
(7,0)
(5,4)
利用 stack 的新方法
(6,2)
目前矩形最大面積: 3
因為 2<4 ,
所以將 (5,4)pop 出來 並更新面積
(6-5)*4=4
(1,1) (2,2) (3,2)
(7,0)
(5,4) 4
利用 stack 的新方法
(6,2)
目前矩形最大面積: 4 因為 2>=2 ,
且上一個 stack 中 pop 掉的 (5,4) 高於自己,所以將左界改成 5
將 (5,2)push 進 stack 中
(1,1) (2,2) (3,2)
(7,0)
(5,2)
利用 stack 的新方法
目前矩形最大面積: 4 因為 0>2 ,
所以將 (5,2)pop 出來 並更新面積
(7-5)*2=4
(1,1) (2,2) (3,2)
(7,0)
(5,2)
重要:最後要加入最右邊的右界
利用 stack 的新方法
目前矩形最大面積: 4 因為 0>2 ,
所以將 (3,2)pop 出來 並更新面積
(7-3)*2=8
(1,1) (2,2) (3,2)
(7,0)
重要:最後要加入最右邊的右界
8
利用 stack 的新方法
目前矩形最大面積: 8 因為 0>2 ,
所以將 (2,2)pop 出來 並更新面積
(7-2)*2=10
(1,1) (2,2)
(7,0)
重要:最後要加入最右邊的右界
10
利用 stack 的新方法
目前矩形最大面積: 因為 0>1 ,
所以將 (1,1)pop 出來 並更新面積
(7-1)*1=6
(1,1)
(7,0)
重要:最後要加入最右邊的右界
10
利用 stack 的新方法
利用 stackLIFO 的性質,我們維護 stack
內元素的遞增,讓每一個左界 ( 雖然說有
可能因為 pop 的關係左移 ) ,都只跟一個
右界行成矩形,效率十分的高。
結語
利用 stack 的性質,我們可以發現很多比一般方法 更快更有效率的方法來解決問題。
其他例題:
TIOJ1176 Cows
給定一排牛 ( 不是一牛排 ) 每頭牛的高度,牠們只能 往右平視或俯視,請問牠們分別能夠看到幾頭牛?
( 如果兩頭牛的高度一樣,那麼左邊的牛的視野只能 看到右邊的牛為止。 )
http://tioj.redirectme.net:8080/JudgeOnline/showpr oblem?problem_id=1176