算法竞赛进阶指南-0x03-前缀和与差分-增减序列
题目
题目描述
给定一个长度为
求最少多少步内可以让数列中所有数字一样大,并在保证最少次数的前提下,最终得到的数列能够有多少种。
输入格式
第
接下来
分析题目
这道题如果通过暴力 dfs 的话,第一个点估计都过不去,所以说就要用一些奇妙的算法了。
介绍一种非常简单的算法:
差分
差分,就是一个数列中第
一个数列
一般为了方便计算,还会让
把数列
这道题中让数列中所有数相同,其实就是让
那么这道题的话,就要先尽量地寻找一正一负的两个数,然后负的数加
令
而最终的得到的序列的种类数是要保证最小步数的,所以第一种操作都是一样的,第二种操作根据和
所以说第一个问的答案就是
注意!,要开 long long!
代码时间
#include <cmath>
#include <iostream>
#define endl '\n'
using namespace std;
const long long N = (long long)1e5 + 5ll;
long long n, last, in, temp, p, q;
int main() {
cin >> n >> last;
for (long long i = 1ll; i < n; i++) {
cin >> in;
temp = in - last;
if (temp > 0ll) p += temp;
if (temp < 0ll) q -= temp;
last = in;
}
cout << max(p, q) << endl;
cout << abs(p - q) + 1ll;
return 0;
}