AcWing 100.增减序列

给定一个长度为 nn 的数列 a1,a2,…,ana1,a2,…,an,每次可以选择一个区间 [l,r][l,r],使下标在这个区间内的数都加一或者都减一。

求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。

输入格式

第一行输入正整数 nn。

接下来 nn 行,每行输入一个整数,第 i+1i+1 行的整数代表 aiai。

输出格式

第一行输出最少操作次数。

第二行输出最终能得到多少种结果。

数据范围

0<n≤1050<n≤105,
0≤ai<21474836480≤ai<2147483648

输入样例:
4
1
1
2
2
输出样例:
1
2
#include <iostream>
#include <cmath>
#include <algorithm>

using namespace std;

typedef long long ll;

//我们有四种操作
//2=<i,j<=n 此时我们进行的是整个区间的操作
//i=1, 2=<j<=n    
//2=<i<=n,j=n+1;
//i=1;j=n+1   //此时对整个区间进行操作,可以直接减去,整个区间同时加1,同时减1,无用操作

const int N=1e5+10;

ll a[N],b[N];

int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        b[i]=a[i]-a[i-1];    差分
        //题中说,最后每个值都相等,那么由于b[i]=a[i]-a[i-1],除了b[1],因为b[1]=a[1],其他的b全为零
        //那么问题就变成如果把b[2]-b[n],变成零的问题
    }
    //差分数组中,根据贪心的思想,我们可以根据情况1,来找一对正负的数,来确定2个边界,正的加1,负的减1,这样更快的趋于0;
    //最后,有可能只剩下正的,或者只剩下负的,如果是零的话答案也就出来了,
    //如果只剩下正的,或者只剩下负的,那么我们可以根据2.3的情况,来让这个数和边界进行消除,这样我们的操作次数就是,pos,neg中绝对值
    //的最大值pos(所有正数的和),neg为所有负数的和
    ll pos=0,neg=0;
    for(int i=2;i<=n;i++)
    {
        if(b[i]>0) pos+=b[i];
        else neg-=b[i];
    }
    
    cout<<max(pos,neg)<<endl;
    
    //所有种数,就是a[1]有多少中不一样的值,当我们将剩余的正数或者剩余的负数,用3的情况来变成零时,a[1],是不变的,也就是加1
    //而当我们用三的情况来变成0时,就是fabs(pos-neg)+1的结果
    cout<<abs(pos-neg)+1<<endl;
    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值