E. Cashback
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Since you are the best Wraith King, Nizhniy Magazin «Mir» at the centre of Vinnytsia is offering you a discount.

You are given an array a of length n and an integer c.

The value of some array b of length k is the sum of its elements except for the Codeforces Round #466 (Div. 2)-E-Cashback(set+dp)_直接插入 smallest. For example, the value of the array[3, 1, 6, 5, 2] with c = 2 is 3 + 6 + 5 = 14.

Among all possible partitions of a into contiguous subarrays output the smallest possible sum of the values of these subarrays.

Input

The first line contains integers n and c (1 ≤ n, c ≤ 100 000).

The second line contains n integers ai (1 ≤ ai ≤ 109) — elements of a.

Output

Output a single integer  — the smallest possible sum of values of these subarrays of some partition of a.

Examples
input
Copy
3 5
1 2 3
output
6
input
Copy
12 10
1 1 10 10 10 10 10 10 9 10 10 10
output
92
input
Copy
7 2
2 3 6 4 5 7 1
output
17
input
Copy
8 4
1 3 4 5 5 3 4 1
output
23
Note

In the first example any partition yields 6 as the sum.

In the second example one of the optimal partitions is [1, 1], [10, 10, 10, 10, 10, 10, 9, 10, 10, 10] with the values 2 and 90 respectively.

In the third example one of the optimal partitions is [2, 3], [6, 4, 5, 7], [1] with the values 3, 13 and 1 respectively.

In the fourth example one of the optimal partitions is [1], [3, 4, 5, 5, 3, 4], [1] with the values 1, 21 and 1 respectively.

题意:给你一个长为n的序列,然后给你一个常数c,让你将序列分成若干段,每一段去掉len/c个最小的数(len为这一段的长度),让你使得最终剩下的数之和最小。

题解:设dp[i]表示前i个数能删掉的元素的最大和,为了确保每次删掉的都是最小的几个元素,我们可以用set维护一下,每次将应想到的直接插入或者删除,然后直接dp即可。

#include<set>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 100005
#define ll long long
ll a[100005],dp[100005],n,c,ans;
multiset<ll>t;multiset<ll>:: iterator it;
int main(void)
{
	scanf("%lld%lld",&n,&c);
	for(int i=1;i<=n;i++)
		scanf("%lld",&a[i]);
	for(int i=1;i<=min(n,c-1);i++)
		t.insert(a[i]);
	for(int i=1;i<=n;i++)
	{
		dp[i+1]=max(dp[i+1],dp[i]);
		if(i+c-1<=n)
		{
			t.insert(a[i+c-1]);
			dp[i+c]=max(dp[i+c],dp[i]+(*t.begin()));
		}
		it=t.find(a[i]);t.erase(it);
	}
	ans=-dp[n+1];
	for(int i=1;i<=n;i++)
		ans+=a[i];
	printf("%lld\n",ans);
	return 0;
}