洛谷P4552 [Poetize6] IncDec Sequence

洛谷P4552 [Poetize6] IncDec Sequence

题目:

在这里插入图片描述

思路:

题目要求原数组的任意区间的值加一或者减一 n n n次之后,数组的所有值都变成一样

n n n的最少值与能得到多少种结果

题目可以转换成把原数组的差分数组的值除了第一项都变成 0 0 0,每一次左端点加一或者减一,右端点减一或者加一

最少次数我们可以再差分数组找到一对对的正数与负数or负数与正数,因为原数组 [ l , r ] [l,r] [l,r]区间加一或者减一,差分数组就是 d i f f [ l ] + 1 ∣ ∣ − 1 diff[l]+1||-1 diff[l]+11并且 d i f f [ r + 1 ] − 1 ∣ ∣ + 1 diff[r+1]-1||+1 diff[r+1]1+1

这样可以一步当两步,所以我们只要求出差分数组除了第一项的正数和与负数的绝对值和,直到正数或者负数用完,剩下的就一步一步加或者减

例:
b i f f [ ] = 1 , 1 , 0 , − 1 , 0 biff[]=1,1,0,-1,0 biff[]=1,1,0,1,0
这样的话我们就可以一次加减处理完

b i f f [ ] = 1 , 1 , 1 , − 1 , 0 biff[]={1,1,1,-1,0} biff[]=1,1,1,1,0
如果正负不平衡的话就是正数和与负数和较大的那个,因为我们处理较大的那一个的时候,顺便可以把较小的处理

能得到多少种结果就是找 d i f f [ 1 ] diff[1] diff[1]能够有多少种不一样的值,这个值就是剩下的一步步加或者减的次数,也就是正负数次数较多的那个减去较小的那个

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main()
{
    ll arr[100100]={0};//原数组
    ll diff[100100]={0};//差分数组
    ll n;
    cin>>n;
    for(int i=1;i<=n;i++) cin>>arr[i];
    diff[1]=arr[1];
    for(int i=2;i<=n;i++) diff[i]=arr[i]-arr[i-1];

    ll sum=0,cont=1;//sum为最少操作次数,cont为最终能得到多少种结果
    //因为无论如何都有一种结果,所以cont初始值为1

    ll z=0,f=0;//正数和与负数和
    for(int i=2;i<=n;i++){//从第二项开始遍历差分数组
        if(diff[i]>0){
            z+=diff[i];
        }else{
            f+=diff[i]*-1;
        }
    }
    //因为我们遍历的时候每一项都加起来了,所以直接找较大的就好了,因为处理较大的时候可以顺便把较小的处理
    sum=max(z,f);
    
    //正数和与负数绝对值和的差值就是我们一次一次加减的次数,也就是最终能得到多少种额外的结果
    cont+=abs(z- f);
    cout<<sum<<endl<<cont<<endl;
    
    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值