本题原选自usaco在2006年11月银组月赛题,传送门:http://poj.org/problem?id=3250
大意:
思路:从1到n分别以1为起点,1到n为终点,维护一个单调递减栈,其中,以i为终点的栈的长度为m就表示包括加上自己,共有m头牛可以看到自己。而我们知道,每头牛是不能看到自己的,所以我们将这n个栈的长度加起来再减去n再输出即可。
拆分讲解:本道题是单调栈的模板题,因此主体程序自然是单调栈的维护了。本蒟蒻喜欢用数组模拟栈,具体思路就是将要进栈 的元素与当前栈尾元素比较,如果违背了单调栈规则,则将标记兼栈元素个数减小,相当于栈尾元素出栈,栈元素个数--,循环执行此操作,直至需进栈的数可符合规则,此时标记++,在此标记位置放上此数,相当于元素进栈。用此方法就可以用数组很好的模拟栈的运行,从而成功地维护一个单调栈。
附上本题代码,单调栈的维护模板就在程序中:
#include<stdio.h>
int main()
{
long long i,n,x,a[80001],t=0,sum=0;
scanf("%lld",&n);
for(i=1;i<=n;i++)
{
scanf("%lld",&x);//读入牛的身高
while(t&&a[t]<=x)//当比这头牛身高低时
t--;//删除当前元
sum+=t;
a[++t]=x;//将这个大的元素放到数组中
}
printf("%lld\n",sum);//输出方案数
return 0;
}
欢迎dalao们指点,大佬Orz