1 条题解

  • 0
    @ 2023-12-1 15:30:26
    //对a上区间l - r上加减一个数
    //对差分数组为b[l] += 1 / -= 1
    //          b[r + 1] -= 1 / += 1
    
    //差分数组的定义
    //b[1] = a[1]
    //b[2] = a[2] - a[1]
    //b[3] = a[3] - a[2]
    //  ....
    //  ....
    //b[n] = a[n] - a[n - 1]
    
    //如果a数组的所有数相同
    //b[1] = a[1]
    //b[2] - b[n] 都=0
    
    //那么原问题就变成了
    //1.如果把一个差分数组b中b[2] - b[n]都变成0,且输出最少次数(最少,意味着可能贪心)
    //注意:此时b[1]可以是任意值,b[n + 1]也可以是任意值
    //2.在1的基础上,b[1]有多少种可能
    
    //对a的1-n区间内进行+1-1操作
    //可以映射为对b的1-n+1区间进行+1-1操作(只不过a数组是一个个+1-1,b数组是对l和r+1两个点进行+1-1)
    
    //可以分成下面四种情况(L表示a中的左端点,R表示a中的右端点)
    //1. 2 <= L <= R <= n - 1
    //此时对应到b数组的操作范围为2~n(因为b是对r+1进行操作,所以总比a的R多1)
    //那对应到差分操作,我们可以把b中2~n任意两个数进行+1-1,其中一个+1,另一个-1
    //2. L == 1,R <= n - 1
    //此时对应到b数组的操作范围为1~n
    //并且b[1] 要么+1要么-1, 另一个在2~n范围内的数也是要么+1要么-1
    //3. 2 <= L,R == n
    //此时对应到b数组的操作范围为2~n+1
    //并且b[n + 1] 要么+1要么-1,另一个在2~n范围内的数也是要么+1要么-1
    //4. L == 1,R == n
    //对应b数组中1~n+1范围,整体+1-1无意义
    
    //由于1情况可以同时把两个数一个+1一个-1
    //基于贪心思想,先使用操作1
    //操作1可以使用几次?
    //当b的2~n中如果不为0的数有大于0的也有小于0的,就可以用操作1
    //因此操作1最多可以用min(p, q)次,(p为b(2~n范围)中所有大于0的数之和,q为所有小于0的数之和)
    //剩下一些要么大于0要么小于0的数,可以用操作2或3,用的次数为abs(p - q)次
    //所有最少操作次数为min(p, q) + abs(p - q)次
    
    //问题二:b[1]有几种可能?
    //在操作2里b[1]会被+1-1
    //所有决定b[1]的值的操作为操作2
    //操作2可以用几次就有多少种取值(因为最后abs(p - q)次操作时,剩下的数要么正要么负,所有操作23的目的是把正数或负数-1或+1变成0,所有最后的操作23一定都是+1或都是-1)
    //最后有abs(p - q)次操作,操作2可以用0,1....abs(p - q)次
    //所有答案是abs(p - q) + 1
    
    
    #include<bits/stdc++.h>
    using namespace std;
    const int N=100010;
    int a[N],b[N];
    typedef long long LL;
    int main()
    {
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
        }
        for(int i=1;i<=n;i++)
        {
            b[i]=a[i]-a[i-1];
        }
        LL p=0,q=0;
        for(int i=2;i<=n;i++)
        {
            if(b[i]>0)
            {
                p+=b[i];
            }
            else 
            {
                q-=b[i];
            }
        }
        cout<<max(p,q)<<endl;
        cout<<abs(p-q)+1<<endl;
        return 0;
    }
    
    • 1

    信息

    ID
    1427
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    3
    上传者