CF688B Suffix Operations

题目链接:CF688B

 

题目大意:

一个数列N个数,每次操作有两种选择,一种是选择一个起点,包括该起点的所有数列的后缀的数都加一,另一种是减一,并且,在操作开始之前,可以选择一个数使之变成任何一个数,也可以不变,问让数列所有数都相等的最少操作次数。

 

思路:

首先考虑最小次数如何得到,对于每一个数ai,要使得他和ai-1相等,则需要操作abs(ai-ai-1)次,则总次数为sum(ai-(ai-1))。现在考虑改变哪个数使得这个sum减小到最少,除去数列两边的数,更改其中一个数会影响abs(ai-ai-1)和abs(ai+1-ai)这两个,所以可以通过比较所有的abs得到最大的,原sum减去最大差值得到最小操作次数

 

实例代码:

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 signed main() {
 5     int t,n;
 6     cin >> t;
 7     while(t--) {
 8         int sum = 0, mx = -1;
 9         cin >> n;
10         int a[200010];
11         for(int i = 1; i <= n; i++) {
12             cin >> a[i];
13         }
14         for(int i = 2; i <= n; i++) {
15             sum += abs(a[i]-a[i-1]);
16         }
17         for(int i = 2; i <= n-1; i++) {
18             if(abs(a[i]-a[i-1]) + abs(a[i+1]-a[i]) - abs(a[i+1]-a[i-1]) > mx) {
19                 mx = abs(a[i]-a[i-1]) + abs(a[i+1]-a[i]) - abs(a[i+1]-a[i-1]);
20             }
21         }
22         mx = max(mx,max(abs(a[2]-a[1]), abs(a[n]-a[n-1])));
23         cout << sum - mx << endl;
24     }
25     return 0;
26 }
View Code

 

posted @ 2020-12-17 16:36  不敢说的梦  阅读(129)  评论(0)    收藏  举报