这道题的解题技巧是将原问题进行转化。题目说明的问题看似是对数组进行k段的划分,其实这个问题可以转化为求k个不同的数组后缀的和,并且其中一个后缀需要是数组自身。在数组本身加上了的基础上,再加上k-1个后缀和,就相当于从左到右依次以1为权重,2为权重,直到k为权重对数组进行分段累加。因此,至要选择k-1个最大的后缀和进行累加就可以得到答案。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
//问题可以等价于在全部数都加上了一次的基础上,选择任意k-1个不同的后缀进行累加求和。
//既然是任意,那么就选取最大的k-1个后缀区间即可得到最优解
const int maxn = 3e5+2;
ll A[maxn];
signed main(){
int n, k;
scanf("%d %d", &n, &k);
A[n] = 0;
for(int i = 0; i < n; i++){ scanf("%lld", &A[i]);}
for(int i = n-1; i>=0; i--){A[i] = A[i+1]+A[i];}
ll ans = A[0];
sort(A+1, A+n);
for(int i = n-1; i> n-k; i--){ans += A[i];}
printf("%lld\n", ans);
return 0;
}