状态Dp[i][j]为前i件物品选j对的最优解
当i=j*2时,只有一种选择即 Dp[i-2][j-1]+(w[i]-w[i-1])^2
当i>j*2时,Dp[i][j] = min(Dp[i-1][j],Dp[i-2][j-1]+(w[j]-w[j-1])^2)
但是在这之前必须先得对w数组进行从小到大的排序,这里用到了快排算法
#include<stdio.h>
int w[2005],dp[2005][1005];void exchange(int *a,int *b)
{
int x=*a;
*a=*b;
*b=x;
}
int mini(int a,int b)
{
return a<b?a:b;
}
int parti(int p,int r)
{
int x=w[r];
int i=p-1;
int j;
for(j=p;j<=r-1;j++)
{
if(w[j]<=x)
{
i++;
exchange(&w[i],&w[j]);
}
}
exchange(&w[i+1],&w[r]);
return i+1;
}
void quicksort(int p,int r)
{
if(p<r)
{
int q=parti(p,r);
quicksort(p,q-1);
quicksort(q+1,r);
}
}
int main()
{
int n,k;
while(scanf("%d%d",&n,&k)!=EOF)
{
int i,j;
for(i=1;i<=n;i++)
scanf("%d",w+i);
quicksort(1,n);
for(i=0;i<=n;i++)
for(j=0;j<=k;j++)
dp[i][j]=0;
for(i=2;i<=n;i++)
for(j=1;j<=k;j++)
{
if(i==2*j)
dp[i][j]=dp[i-2][j-1]+(w[i]-w[i-1])*(w[i]-w[i-1]);
else if(i>2*j)
dp[i][j]=mini(dp[i-1][j],dp[i-2][j-1]+(w[i]-w[i-1])*(w[i]-w[i-1]));
}
printf("%d\n",dp[n][k]);
}
return 0;
}