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