ACwing增减序列题解

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

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

输入格式
第一行输入正整数n。

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

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

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

数据范围
0< n ≤ 10^5^,
0≤ ai <2147483648

输入样例:
4
1
1
2
2

输出样例:
1
2

这道题没有想到多半是因为对差分的理解不够到位.没有想到将问题转化为差分,不过这是做的第一道差分题,情有可原(其实是本人太菜了)

差分解决一段区域同时增加或减少的问题,给区间【L,R】上都加上一个常数c,则b[L] += c , b[R + 1] -=c

首先求出a的差分序列b.由上我们可以分析得出,本题可以任选b中的两个数,一个+1,另一个-1,目标是把b2,b3,…bn变为全0。最终得到的数列a就是由 n 个 b1 构成的.

任选两个数的方法可分为四类
1、2 <= i , j <=n(优先)
2、i = 1, 2 <=j <=n
3、2 <= i <= n , j = n + 1
4、i = 1, j = n + 1(没有意义)

设b2,b3....bn中正数总和为p,负数总和的绝对值为q。首先以正负数匹配的方式尽量执行1类操作,可执行min(p,q)次。剩余|p - q|个为匹对,每个可以选与b1或b(n + 1)匹配,即执行2 或 3 类操作,共需|p - q|次

综上所述,最少操作次数为min(p,q) + |p - q|。根据|p - q|次第2、3类操作的选择情况,能产生|p - q| + 1中不同的b1的值,即最终得到的序列a可能有|p - q| + 1 种

AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=100005;
int 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];
    }
    long long q=0,p=0;
    for(int i=2;i<=n;i++)
    {
        if(b[i]<0) p-=b[i];
        else q+=b[i];
    }
    cout<<max(p,q)<<endl;//min(p,q)+|p-q|其实就是max(p,q)
    cout<<1+(int)fabs(p-q);
}

参考博客:https://www.cnblogs.com/vanhopex/p/15968351.html

posted @   Crab2016  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示