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组,分别是i,i+k,i+2*k,i+3*k...(1<=i<=k),有x=n%k个组元素个数是n/k+1个,问题就转化为k组内
相邻元素差值的和的最小值,这时就需要对数组进行排序,只有每组内的元素都是有序的,每组内的相邻元素的
差值才会最小,接着就是在k组内分x组长度为n/k+1,这时就需要dp,dp[i][j],i是分了i组,j组长度是n/k+1;dp方
程为dp[i][j]=max(dp[i-1][j]+dp[i-1][j-1])+(a[i*n/k+j+1]-a[i*n/k+j]),ans=a[n]-a[1]-dp[k][x],a[i*n/k+j+1]-a[i*n/k+j]是要
从分第i组是,第i组的第1个元素与第i-1组的最后一个元素的差值。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=500000+100;
int a[maxn];
int s[maxn];
int bbs(int x)
{
if(x<0)
return -x;
return x;
}
int dp[5500][5500];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
memset(dp,-1,sizeof(dp));
int sum=a[n]-a[1];
int q=n/k;
int x=n%k;
dp[0][0]=0;
for(int i=1;i<=k;i++)
{
for(int j=0;j<=x;j++)
{
int df;
if(j==0)
df=dp[i-1][j];
else
df=max(dp[i-1][j],dp[i-1][j-1]);
if(df<0)
continue;
if(i==k&&j==x)
dp[i][j]=df;
else
dp[i][j]=df+a[i*q+j+1]-a[i*q+j];
}
}
int ans=sum-dp[k][x];
cout<<ans<<endl;
return 0;
}