url: https://www.luogu.com.cn/problem/P4552
tag:
差分
思路:
说是一道差分的题,但觉得更像是脑筋急转弯的那种感觉。为了求出最少的操作次数,可以依次求a(i) - a(i-1),表示相邻两个数的差,然后将正的差和负的差分别求和,之后取这两个和的最大值就是最少的操作次数,因为对于差分来说,如果要对原数组的某一个区间加上1就是让这个区间的第一个数加1最后一个数的后一个数减一,所以加1和减1会有重叠,因此重叠的部分只需要算一次就好,然后剩下的不重叠的再单独算,所以最少的操作次数就是max(q, p),而对于多少种情况来讲,其实看的是a(1),因为最后数都一样的话,那么对于差分数组(代码没有)来说,第一个数会影响全部的数。所以只要把有可能会对第一个数产生影响的次数加在一块再加上本身一种情况就是最多可能的结果数。而这种会影响的次数其实就是不重叠的次数,也即max(p, q) - min(p, q),(min(p, q)用来表示重叠的次数)。
代码:
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
long long a[N], b[N];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++) cin >> a[i];
long long p = 0, q = 0;
for (int i = 2; i <= n; i ++)
{
long long tmp = a[i] - a[i - 1];
if (tmp > 0) p += tmp;
else q -= tmp;
}
cout << max(q, p) << '\n' << max(q, p) - min(q, p) + 1 << endl;
return 0;
}