- 增减序列 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;
}