• 差分+贪心:IncDec序列


    原题

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

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

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

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

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

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

    数据范围
    0<n≤1050<n≤105
    0≤ai<21474836480≤ai<2147483648
    输入样例:

    4
    1
    1
    2
    2
    输出样例:

    1
    2

    思路:首先这题一个重点,就是区间[l,r][l,r]的修改操作。因为这道题目的修改操作有一个特性,就是只加一或者只减一,而不是+x+x,也不是−x−x,所以说我们并不需要用到高级的数据结构,线段树和树状数组,而只是需要用差分即可。
    差分:差分的定义,可以见《算法竞赛进阶指南》的P21页。
    介于第一版没有差分,这里说一下定义:对于一个给定的数列A,它的差分数列B定义为, B[1]=A[1],B[i]=Ai−Ai−1(2<=i<=n)B[1]=A[1],B[i]=Ai−Ai−1(2<=i<=n)
    这里只说性质,也就是把序列A的区间[L,R][L,R]加d,也就是把Al,Al+1....ArAl,Al+1....Ar都加上d,其实就是它的差分序列B中,Bl+d,Br+1−dBl+d,Br+1−d,其他的位置统统不改变。
    因此在这道题目中,我们就可以利用这个非常有用的性质,因为我们只要求A序列中所有的数相同,而不在意这些方案具体是什么,所以说我们就可以转化题目,也就是将对A序列的+1,−1+1,−1操作,让A序列相同,改成目标把B2,…,BnB2,…,Bn变成全0即可,也就是A序列全部相等。而且最后得到的序列,就是这n个B1B1
    贪心:因为我们有上面所说的性质,那么我们就可以,每一次选取Bi和BjBi和Bj,2<=i,j<=n2<=i,j<=n,而且这两个数,一个为正数,一个为负数,至于为什么要是正负配对,因为我们是要这个B序列2~n都要为0,所以这样负数增加,正数减少,就可以最快地到达目标为0的状态。
    至于那些无法配对的数BkBk可以选B1B1或者BnBn,这两个不影响的数,进行修改。
    所以说我们这道题目得出的答案就是,最少操作数min(p,q)+abs(p−q)=max(p,q)min(p,q)+abs(p−q)=max(p,q),然后最终序列a可能会有abs(p−q)+1abs(p−q)+1种情况。p为b序列中正数之和,而q为b序列中负数之和

    作者:秦淮岸灯火阑珊
    链接:https://www.acwing.com/solution/acwing/content/816/
    来源:AcWing

    代码:·要开long long!!!!(别问我为什么这么说)

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    long long a[N],b[N],n;
    int main(){
    	std::ios::sync_with_stdio(false);
    	cin>>n;
    	long long zans=0,fans=0,ans1,ans2;
    	for(int i=1;i<=n;i++)cin>>a[i];
    	for(int i=1;i<=n;i++)b[i]=a[i]-a[i-1];
    	for(int i=2;i<=n;i++)
    	if(b[i]>0)zans+=b[i];
    	else fans+=b[i];
    	ans2=abs(fans+zans);
    	fans=abs(fans);
    	ans1=max(fans,zans);
    	cout<<ans1<<endl<<ans2+1; 
    	return 0;
    }
    

      

  • 相关阅读:
    【IDEA】(4)---很好用的DEBUG功能
    【IDEA】(3)---非常实用提高开发效率和水平的插件
    【IDEA】(2)---MAC代码模版
    【IDEA】(1)---MAC下常用快捷键
    Shell(2)—数组
    MySQL(12)---纪录一次left join一对多关系而引起的BUG
    MySQL(11)---约束
    Shell(1)---变量
    算法(2)---算法复杂度理论
    MySQL(10)---自定义函数
  • 原文地址:https://www.cnblogs.com/myhnb/p/11248066.html
Copyright © 2020-2023  润新知