Pla
Posted JZYshuraK_彧
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pla相关的知识,希望对你有一定的参考价值。
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驶过,不赘述。
以上是关于Pla的主要内容,如果未能解决你的问题,请参考以下文章