为了能到远方,脚下的每一步都不能少.|

园龄:粉丝:关注:

2021-08-11 14:15阅读: 158评论: 0推荐: 1

增减序列

增减序列

最终的目的是让整个序列相等

操作只有一种使[l,r]区间全都+1

既然整个序列相等,那么整个序列的差分序列应为0

操作的话就可以转化为a[l]+=1a[r+1]=1

求的是最少操作次数

通过原数列,我们先求一个原始的差分序列,然后每次操作使,正数-1,负数+1,这样就使差分序列往目标:靠近 0序列
(当然差分序列第1项不用为0,而且首项可以为任何数,思考为什么?)

设正数的和p,负数绝对值和q,那么就很容易的到一个最少操作次数 max(p,q)
(简单描述下怎么来的,操作min(p,q)次后,p,q中小的变为0,还剩abs(pq)次 ,所以最少操作次数 min(p,q)+abs(pq)=max(p,q))

至于最少操作后的结果

操作min(p,q)次后,那么一定剩下几项不为0
此时可以考虑两中情况

  1. 与差分序列首项想相加减
    这种情况因为改变首项,所以最终序列会改变,故会得到abs(pq)种序列

  2. 与第n+1项相加减
    这种情况并不改变首项,只有一种序列(第n+1项无论怎么变,都不影响最终序列,也可以思考为什么)

总的来说会得到abs(pq)+1种方案

  • code
#include<iostream>

using namespace std;
const int maxn=1e5+10;
int a[maxn];int n;
int cf[maxn];
long long p=0,q=0;
long abs(long x){
    return x<0?-x:x;
}
int main(){
    cin>>n;
    for(int i=1;i<=n;++i){
        cin>>a[i];
        cf[i]=a[i]-a[i-1];
    }
    for(int i=2;i<=n;++i){
        if(cf[i]>0) p+=cf[i];
        if(cf[i]<0) q-=cf[i];
    }
    cout<<max(p,q)<<endl<<abs(p-q)+1<<endl;return 0;
}

本文作者:归游

本文链接:https://www.cnblogs.com/guiyou/p/15127976.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   归游  阅读(158)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起