目录:
题目
分析:
团队中一堆dalao用单调栈AC,只有我默默的将贪心交了上去,而且居然还AC了:
其实只是在普通的贪心上加了剪枝,那就是记录第i头牛的第一只比自己高的牛,为什么呢?
这是因为我们如果可以加上点i,那么比点i还矮的肯定不用说,那么我们就可以选择跳过了
代码(贪心):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#define LL long long
#define M 200010
using namespace std;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int x[80001],f[80001],g[80001];
long long ans=0;
int main()
{
// freopen("badhair.in","r",stdin);
// freopen("badhair.out","w",stdout);
int n=read();
for(int i=1;i<=n;i++) x[i]=read();
for(int i=n-1;i>0;i--)
{
int j=i+1;
while(j<=n)
{
if(x[i]<=x[j]) {g[i]=j;break;}
f[i]+=f[j]+1;
if(g[j]) j=g[j];
else break;
}
}
for(int i=1;i<n;i++) ans=(long long)ans+f[i];
printf("%lld",ans);
fclose(stdin);
fclose(stdout);
return 0;
}
代码(单调栈):
#include<cstdio>
#include<cctype>
#define file(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout)
using namespace std;
int n,a[80001];
long long ans;
inline void in(int &f)
{
f=0;char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) f=f*10+c-48,c=getchar();
return;
}
void print(long long x)
{if (x>9) print(x/10);putchar(x%10+48);return;}
int main()
{
file(badhair);
in(n);
int cnt=1,s;
for(int i=1;i<=n;i++)
{
in(s);
while (s>=a[cnt]&&cnt>=1) cnt--;
ans+=cnt;
a[++cnt]=s;
}
print(ans);
fclose(stdin);fclose(stdout);
return 0;
}