题目链接
题意
给定一条链,链上有n个结点,每个点有一个点权
试为每个点分配一个正整数,使得:
- 若两个相邻点的点权相等,则他们分配的数字也相等
- 否则点权大的点分配的数字应比点权小的大
分析
这道题其实写起来不是很难,但是思路可能有一点难想吧。
我们发现,如果只考虑上升的序列,这道题就很简单,就直接加呗,为什么下降会出现问题呢?因为下降不能直接减,下降如果直接减的话,可能会出现负数,而题意中是不允许有负数的,所以要用一下逆向思维。
怎么逆向呢?正着下降的话不就是从后往前上升吗?所以我们每次只考虑上升的,因为上升的就直接+1就完了,于是这道题就正着跑一遍上升,倒着再跑一遍,如果这个数比前一个数大,就需要+1,小的话不管,等于也相等,最后要注意两种情况取最大值。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e6+10;
int ans[N],a[N];
int main(){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
ans[i]=1;//初始化为1,因为最小用1
}
for(int i=2;i<=n;i++){
if(a[i]>a[i-1])
ans[i]=ans[i-1]+1;
else if(a[i]==a[i-1])
ans[i]=ans[i-1];
}//正着跑
for(int i=n-1;i;i--){
if(a[i]>a[i+1])
ans[i]=max(ans[i],ans[i+1]+1);
else if(a[i]==a[i+1])ans[i]=ans[i+1];
}//倒着跑
long long res=0;
for(int i=1;i<=n;i++)
res+=ans[i];//统计答案,不开longlong会挂一个点
printf("%lld
",res);
}
其实题真的只是普及-的难度,但是为啥没人写啊,我写的题干太长了?