IncDec序列
题目描述:
给定一个长度为 n 的数列 a1,a2,…,an,每次可以选择一个区间[l,r],使下标在这个区间内的数都加一或者都减一。
求至少需要多少次操作才能使数列中的所有数都一样,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
输入格式:
第一行输入正整数n。
接下来n行,每行输入一个整数,第i+1行的整数代表ai。
输出格式:
第一行输出最少操作次数。
第二行输出最终能得到多少种结果。
数据范围:
0<n≤10^5,
0≤ai<21474836480≤ai<2147483648
输入样例:
4
1
1
2
2
输出样例:
1
2
解题思路:
随意在[l,r] +1或者-1,具体分一下几种情况:
1. l,r都在中间 2<=l,r<=n。
2.前缀,l==2,2<=r<=n。
3.后缀,r==n,2<=l<=r。
4.全部,l==2,r==n,(无意义)。
修改方案可以是先局部修改,采用1,然后前后修改,采用2,3
操作次数:min(z,f)+abs(z - f)==max(z,f)
方案数:min(z-f)+1
#include<iostream> #include<algorithm> #include<cstdio> #include<string> using namespace std; #define ll long long const int N = 100010; int a[N]; int main() { int n; cin >> n; for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = n; i > 0; i--) a[i] -= a[i - 1]; //倒序求差分数组 ll z = 0, f = 0; for (int i = 2; i <= n; i++) { //求差分数组中正负值 if (a[i] > 0)z += a[i]; else f -= a[i]; } printf("%lld %lld ", max(z,f), abs(z - f) + 1); return 0; }