安亦行

题目链接

题意

给定一条链,链上有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\n",res);
}

其实题真的只是普及-的难度,但是为啥没人写啊,我写的题干太长了?

posted @ 2020-05-03 17:26  An_Fly  阅读(132)  评论(0编辑  收藏  举报