题目:http://poj.org/problem?id=3250
想法:运用 单调栈,这次是单调递减。每条牛用(h,w)表示,h表示牛的身高,ww记录 被这头牛看到头顶的牛 的个数,准备入栈的牛比栈顶牛矮,直接入栈;反之(比栈顶高或 一样高),不入栈,此时栈顶b[l-1].w是这一条牛所有可以看到其他牛头的总数,加入sum,出栈,若栈不空,此时栈顶b[l-1].w要+1+b[l].w,1表示出栈的那一头牛,b[l].w表示出栈的那一条牛可以看到的牛,此时栈顶牛自然也能看到。(最后加一条比所有牛都高的牛,确保都出栈)
注意:WA了一次,一开始我把 看到头的总和sum设为int,但是极有可能超过int范围。例如,有80000头牛,从前往后越来越矮,sum=79999+79998+79997+...+2+1+0=(79999+0)*80000/2>int_max。故sum设为long long 型,b[l].w设为long long 型,是为了避免强制转换
代码:
1 #include<stdio.h> 2 struct node{ 3 int h;//h牛的身高,w记录 被这头牛看到头顶的牛的个数 4 long long w; 5 }b[80005];//栈 6 int a[80005];//牛的高度 7 int main(){ 8 int n,i,l=0; 9 long long sum=0; 10 scanf("%d",&n); 11 for(i=0;i<n;i++){ 12 scanf("%d",&a[i]); 13 } 14 a[n]=1000000005;//最后加一条牛比所有牛都高,确保,都出栈 15 for(i=0;i<=n;i++){ 16 if(l==0||a[i]<b[l-1].h){//如果栈空 或 该牛比栈顶牛矮 入栈 17 b[l].h=a[i]; 18 b[l].w=0; 19 l++;//入栈 20 } 21 else{//要出栈 22 sum+=b[l-1].w; 23 l--;//出栈 24 if(l){ 25 b[l-1].w+=1+b[l].w; 26 } 27 i--; 28 } 29 } 30 printf("%lld",sum); 31 return 0; 32 }