1. 程式人生 > >Pla

Pla

sin return 都是 ++ print pre 答案 pri com

Pla(jdoj1006)

    題目大意:給你n個矩形,並排放在一起,你的目的是將所有的矩形全部染色。你每次染的形狀為一個矩形,問:最少需要染多少次?

    註釋:n<=10^6,wi , hi<=2^31-1,其中,wi和hi分別是矩形的寬和高。

      想法:第一想法是貪心,顯然是不對的。在此,我們介紹一種數據結構——單調棧。顧名思義,就是維護棧裏的元素是單調的。那麽,在本題中,我們維護一個單調棧,每次加入一個數,判斷棧頂,如果棧頂大於該數,則彈出,貢獻+1,如果小於等於該數,則將該數壓如棧內。最後,統計棧內元素個數,相同高度視為一種元素,貢獻+=元素個數。

      下面,我們證明,為什麽這玩意兒是對的。

      首先,先觀察每次操作。如果壓入的元素小於棧頂,我們設棧頂元素為h,除棧頂外的第一個元素的高度是 h - a ,想壓入的元素的高度為 h - b ,那麽,無論如何,棧頂高度的 min ( a , b ) 必須需要一次單獨的染色。所以,這時,對於答案的貢獻+1。然後,將棧頂元素的 a 染色,此時,剩余的高度與除棧頂外的第一個元素的高度是相同的,我們將它們視為一個元素,即——彈出。以此類推...最後,我們在棧中剩下的元素都是不相同的,這樣,必須在需要元素個數次染色。

      最後,附上醜陋的代碼......

 1 #include <iostream>
 2 #include <cstdio>
 3
using namespace std; 4 int a[100100]; 5 int top=0; 6 int main() 7 { 8 int n; 9 int w,h;//寬與高,顯然發現,寬在本題中是沒有地位的 10 scanf("%d",&n); 11 int ans=0; 12 for(int i=1;i<=n;i++) 13 { 14 scanf("%d%d",&w,&h); 15 a[++top]=h;//存高 16 while(1)//將元素壓入棧中,並執行我們已經證明過的操作。
17 { 18 if(a[top]>a[top-1]) break; 19 else if(a[top]-a[top-1]==0)//在相等時,我們只需把棧頂元素彈出即可 20 { 21 top--; 22 } 23 else 24 { 25 top--; 26 a[top]=h; 27 ans++; 28 } 29 } 30 } 31 printf("%d",ans+top);//統計棧內剩余元素個數,即可 32 return 0; 33 }

      小結:錯誤

          1.沒有判斷相等,但不至於爆蛋。

          2.一直在裸貪心,不會轉換想法。

          3.這與NOIP の某道T1類似,但是那道題被我dp駛過,不贅述。

    轉載請註明:http://www.cnblogs.com/ShuraK/p/7853155.html

Pla