其实这道题比起其他年份的T1还是算难的。
花费时间:40min+
我的做法是:
用一个栈,来存某一段。
看图理解
我们先将第一段橙色的入栈,因为这是第一段,所以次数是st[top];
然后清空栈,将绿色的入栈,需要的次数是st[top]-st[1]=2;(因为是递增的,所以已经清空的上一段最后一个一定比当前这一段的第一个高,所以在之前就可以将这一段的这个高度给覆盖掉,所以需要的次数是最大值减最小值)
以此类推。
时间复杂度O(n)
检查时发现,宽度为1的时候要单独处理
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int M=100009;
int n,a[M],maxn,ans;
int st[M],top;
bool first;
int main()
{
freopen("block.in","r",stdin);
freopen("block.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),maxn=max(maxn,a[i]);
if(n==1) {printf("%d",a[1]);return 0;}
int top=0;
a[0]=-1;
for(int i=1;i<=n;i++)
{
if(a[i]>=a[i-1]) st[++top]=a[i];
else
{
if(!first)
{
ans+=st[top];
first=1;
}
else ans+=st[top]-st[1];
top=0;
st[++top]=a[i];
}
}
ans+=st[top]-st[1];
printf("%d",ans);
return 0;
}
/*
8
2 3 4 1 3 3 0 4
10
*/