题意:
一个数组,有三种操作
选中i位置,1~i位置,所有的数 - 1
选中i位置, 1~i位置,所有的数 + 1
所有位置 + 1
要求最后所有的数都为0
思路:
区间整体处理问题,可以考虑差分数组,
-
b_1 - 1, b_{i +1} + 1
-
b_i - 1
-
b_i + 1
就相当于将b数组变为0
统计b数组的正负即可
#include <bits/stdc++.h>
#define endl '\n'
#define IOS ios::sync_with_stdio(false);
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
int T, n;
ll a[N], b[N];
int main()
{
//IOS; cin.tie(0), cout.tie(0);
cin >> T;
while (T--)
{
cin >> n;
ll no1negtive = 0, no1postive = 0;
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
b[i] = a[i] - a[i - 1]; //差分数组思想
if (i != 1 && b[i] < 0) //差分数组性质,对于操作1相当于 b1 - 1, b[i](i 除了1) + 1
{
no1negtive -= b[i]; //记录除了1外的负数的总和
}
else if (i != 1)
{
no1postive += b[i]; //对于操作2相当于b[i] - 1, 在任何位置都行,但是这里除1外
}
}
ll ans = 0;
ans += no1negtive; //先把除1外的所有负数变0
b[1] -= no1negtive; //b[1]减去相应的代价
if (b[1] <= 0) //b[1]小于0,通过操作3来调整
{
ans += -1 * b[1] + no1postive; //b[1]要调整的次数 + 要将正数变0的次数
cout << ans << endl;
}
else
{
ans += b[1] + no1postive; //b[1]是正数直接用操作2进行调整
cout << ans << endl;
}
}
return 0;
}