【题解】codeforces1197 C. Array Splitting⭐⭐⭐【思维 贪心】

codeforces1197 C. Array Splitting

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.

Input

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).

Output

Print the minimum cost you can obtain by dividing the array a into k nonempty consecutive subarrays.

Examples

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

Hint

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;
}


你可能感兴趣的:(贪心)