You've got array A, consisting of n integers and a positive integer k. Array A is indexed by integers from 1 to n.
You need to permute the array elements so that value

The first line contains two integers n, k (2 ≤ n ≤ 3·105, 1 ≤ k ≤ min(5000, n - 1)).
The second line contains n integers A[1], A[2], ..., A[n] ( - 109 ≤ A[i] ≤ 109), separate by spaces — elements of the array A.
Print the minimum possible value of the sum described in the statement.
3 2 1 2 4
1
5 2 3 -5 3 -5 3
0
6 3 4 3 4 3 2 5
3
In the first test one of the optimal permutations is 1 4 2.
In the second test the initial order is optimal.
In the third test one of the optimal permutations is 2 3 4 4 3 5.
思路:可以将最后形成的这个序列拆成k组,其中ai和ai+k为一组。将原序列排序后,将其拆成连续的k组,然后即可拼成这个最后的序列。这k组中,有a=n%k组的长度为len1=n/k+1,有b=k-n组的长度的len=n/k。然后用dp[i][j]去求最小解。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int T,t,n,m,a,b,len1,len2,ans;
int num[300010];
int dp[5010][5010],INF=1e9;
int main()
{
int i,j,k,u;
INF=INF*2+10;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
len2=n/m;
len1=len2+1;
a=n%m;
b=m-a;
sort(num+1,num+1+n);
for(i=0;i<=a;i++)
for(j=0;j<=b;j++)
{
dp[i][j]=INF;
k=i*len1+j*len2;
if(i>0)
dp[i][j]=min(dp[i][j],dp[i-1][j]+num[k]-num[k-len1+1]);
if(j>0)
dp[i][j]=min(dp[i][j],dp[i][j-1]+num[k]-num[k-len2+1]);
if(i+j==0)
dp[i][j]=0;
}
printf("%d\n",dp[a][b]);
}