IncDec Sequence(增减序列)Acwing102
题目:
给定一个长度为 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)中的元素加减一操作使得整个数列为常数列最少需要操作多少次,最终的常数列有多少种
这种需要对区间每个元素操作的方法很快就能想到 前缀和与差分, 这题使用差分序列完成。
差分决策:
只需要将[2 ~ N]中的差分序列全部变为0即可。
选择区间的可能:
1、 2 <= i , j <= N 尽可能的选择一正一负的i ,j保证接近目标
2、 i = 1, 2 <= j <= N
3、 j = 1, 2 <= i <= N
——2 、3 将i,j配对化为其中一个
4、 i = 1 , j = N 毫无意义
其中假设序列中正整数总和为p、负整数为q。则先采用第一种方案最少需要执行min(p, q)种操作。
剩余| p - q |个未匹配的采用第2、 3种方案化为其中的一个数。所以总操作次数未min(p, q) + |p - q|
一共可以产生|p - q| + 1种数列
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 1e5 + 10;
int a[N];
int main(){
int n;
cin >> n;
for(int i = 1; i <= n; i++)cin >> a[i];
for(int i = n; i > 1; i-- ) a[i] -= a[i - 1];//计算差分序列
LL pos = 0, neg = 0;
for(int i = 2; i <= n; i++){
if(a[i] > 0)pos+=a[i];//计算正整数的总和
else neg -= a[i];//计算负整数的总和
}
cout << min(pos, neg) + abs(pos - neg) << endl;
cout << abs(pos - neg) + 1 << endl;
return 0;
}