原题传送门:http://poj.org/problem?id=3250
ps:有的浏览器显示题目中的图有问题,建议用谷歌chrome
题意:n头牛全部朝向东面站成一列,每头牛可以看到前方比它矮的牛的发型(可能被比它高或者等高的牛阻断视野),给出牛的只数和每头牛的身高,求每头牛可以看到的发型之和
思路:每头牛可以看到的发型之和,其实也就是每头牛的发型被看到的次数之和。建立一个降序的单调栈,那么每个元素出栈后剩下的元素个数也就是这个元素被看到的次数。
解决方案:建立一个降序单调栈,让所有元素依次进栈并维护栈内元素单调性,累加所有的元素出栈时剩下的元素个数
ac代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const long long maxn=8e4+100; //最大数据范围
int s[maxn]; //建立一个足够大的数组来模拟单调栈
int main()
{
int t,m,n,j,len;
long long ans; //预估l最大值,有爆int的危险,用long long
while(scanf("%d",&t)!=EOF)
{
len=0;ans=0;
for(j=0;j<t;j++)
{
scanf("%d",&m);
while(len&&m>=s[len-1])ans+=--len; //维护单调栈,同时更新ans的值
s[len++]=m;
}
printf("%I64d\n",ans+len*(len-1)/2); //不要忘了加上栈内剩余的元素
}
return 0;
}
小结:重点在于问题的转化,明确思路后实现起来并不难。如果没有转化,也可以直接手动建立模拟,但是实现起来显然复杂了很多,在这里就不详说了。
单调栈相关传送门:
http://blog.csdn.net/silence__bug/article/details/46882209
有什么意见或者建议,欢迎指导~,有什么不理解的,也可以在留言板上提出,谢谢~~~