问题描述
- 题目要求每个数与前面一个数之差的绝对值之和最小(默认最左端和最右端是
0
0
0)。
- 你能用一个代价将某个数减少
1
1
1。
- 使得每个数与前面一个数之差的绝对值之和以及代价之和最小并输出。
思路分析
- 我们考虑一个数和他左右相邻的数。
- 如果两个数都比他大的话,他去减一,那么贡献将会是
+
3
+3
+3。
- 一个数比他大,一个数比他小的话,他去减一,贡献将会是
+
1
+1
+1。
- 两个数都比他小,他去减一,那么贡献将会是
−
1
-1
−1。
- 所以我们只需要找到每一个比他左右都大的数,并且把他减到左右最大的那个数即可。
代码如下
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 4e5 + 10;
ll sum;
ll a[maxn];
ll maxx;
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
sum = 0;
int n;
cin >> n;
a[0] = 0;
a[n + 1] = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
sum += abs(a[i] - a[i - 1]);
}
sum += a[n];
for (int i = 1; i <= n; i++)
{
if (a[i] > a[i - 1] && a[i] > a[i + 1])
{
sum -= (a[i] - max(a[i - 1], a[i + 1]));
}
}
cout << sum << endl;
}
return 0;
}