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 }

浙公网安备 33010602011771号