2021--4-13 增减序列(差分)

  1. 增减序列 https://www.acwing.com/problem/content/102/

题目要求最少的操作次数和得到多少种结果如果a数组来存储所有的整数那么则需要把a数组在区间[l,r]上的所有数字都加上1或者-1,相当于差分数列种bl +1/-1 br+1 -1/+1,这样就简便了很多,所以目标变对b2到bn操作,把b2到bn都变成0
对差分序列的操作一共有四种

1、对 bl和br操作,2<=l,r<=n,因为差分的是一个加一个减,所以在这个区间内找到一正一负因此可以更高效的让二者趋近于0,所以最小操作数就是 min(pos,neg)+abs(pos - neg) = max(pos,neg);

2、对b1和br操作 ,2<=r<=n;正负在操作一抵消一部分后,还剩下abs(pos-neg)没有变为0,则进行操作2或3来将其变为0,操作数为abs(pos-neg); 得到的结果数为abs(pos,neg)

3、对bl和bn+1操作 2<=l<=n;

4、对b1和bn+1操作 因为这步相当于对所有数字都加一或减一再进行操作,这一步全体增减的步骤会让操作数+1肯定不是最优解所以没有意义

注意
因为ai比较大所以要用longlong
对2到n进行一个个正负的匹配而不是从1到n!!
可以不用创建一个b数组来存储差分数组,但是要逆序更新覆盖原数组形成差分数组

#include<iostream>
using namespace std;
#include<algorithm>
const int n = 100010;
typedef long long ll;
ll a[n],b[n];

int main()
{
    int n;
    cin>>n;
    ll neg = 0,pos = 0;
    for(int i = 1;i<=n;i++)cin>>a[i];
    //for(int i = 2;i<=n;i++)b[i] = a[i]-a[i-1];
    for(int i = n;i>=2;i--)a[i] -= a[i-1];
  //  b[1] = a[1];
    for(int i = 2;i<=n;i++)//从2开始循环,对2到n进行操作,为了把2到n都为0
    {
        if(a[i] > 0)pos += a[i];
        else neg -= a[i];
    }
    cout<<max(pos,neg)<<endl;
    cout<<abs(pos - neg)+1<<endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值