You are given a sorted array a1,a2,…,an (for each index i>1 condition ai≥ai−1 holds) and an integer k.
You are asked to divide this array into k non-empty consecutive subarrays. Every element in the array should be included in exactly one subarray.
Let max(i) be equal to the maximum in the i-th subarray, and min(i) be equal to the minimum in the i-th subarray. The cost of division is equal to ∑i=1k(max(i)−min(i)). For example, if a=[2,4,5,5,8,11,19] and we divide it into 3 subarrays in the following way: [2,4],[5,5],[8,11,19], then the cost of division is equal to (4−2)+(5−5)+(19−8)=13.
Calculate the minimum cost you can obtain by dividing the array a into k non-empty consecutive subarrays.
The first line contains two integers n and k (1≤k≤n≤3⋅105).
The second line contains n integers a1,a2,…,an (1≤ai≤109, ai≥ai−1).
Print the minimum cost you can obtain by dividing the array a into k nonempty consecutive subarrays.
inputCopy
6 3
4 8 15 16 23 42
outputCopy
12
inputCopy
4 4
1 3 3 7
outputCopy
0
inputCopy
8 1
1 1 2 3 5 8 13 21
outputCopy
20
In the first test we can divide array a in the following way: [4,8,15,16],[23],[42].
给出一个序列 分成k块 求最小的 每块最大最小值之差 之和
拿到这种题, 不妨先试着推导推导. 既然要求最大最小值之差, 我们可以试着从差分入手.(即相邻两数之差)
之后可以发现, 无论如何分成k快, 其代价之和一定是某些差分序列的和(仔细思考), 因为我们要求代价最小, 应该去掉最大的k-1个差分序列.
对于这k-1个差分序列, 我们将其中间做一个切割分块, 甚至可以单独一个数分为一块, 这样其代价一定为0. 然后再把剩余的块分在一起
没有思路时不妨拿笔写写试着推导, 不要只看着
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define ms(x, n) memset(x,n,sizeof(x));
typedef long long LL;
const int inf = 1<<30;
const LL maxn = 3e5+10;
int n, k, a[maxn];
bool is[maxn];
struct node{
int d, i;
}d[maxn];
bool cmp(node x, node y){return x.d > y.d;}
int main()
{
cin >> n >> k;
for(int i = 1; i <= n; ++i){
cin >> a[i];
if(i==1){
d[1].d = 0, d[1].i = 1;
continue;
}
d[i].d = a[i]-a[i-1];
d[i].i = i;
}
sort(d+1, d+1+n, cmp);
for(int i = 1; i <= k-1; ++i)
is[d[i].i] = true;
int ans = 0, tmin = inf, tmax = 0;
for(int i = 1; i <= n; ++i){
tmin = min(tmin, a[i]);
tmax = max(tmax, a[i]);
if(is[i+1] || i==n){
ans += tmax-tmin;
tmax = 0, tmin = inf;
}
}
cout << ans << endl;
return 0;
}