#include<stdio.h>
#include<algorithm>
using namespace std;
#define Tire(a,b) (a-b)*(a-b)
int a[2005];
int dp[2005][1005];
/*证明:假设四个从小到大的数:a、b、c、d,只需证明以下表达式成立即可:
(a-b)^2+(c-d)^2< (a-c)^2+(b-d)^2
(a-b)^2+(c-d)^2< (a-d)^2+(b-c)^2
*/
int main()
{
int n,k,i,j,t;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(i=0;i<=n;i++)
for(j=0;j<=k;j++) dp[i][j]=0;
for(j=1;j<=k;j++)//dp[][]统计到 i 时 j 步最小
{
for(i=j*2;i<=n;i++)
{
if(i==j*2){dp[i][j]=dp[i-2][j-1]+Tire(a[i],a[i-1]);continue;}
dp[i][j]=dp[i-1][j];
if( ( t=Tire(a[i],a[i-1])+dp[i-2][j-1] )<dp[i][j])dp[i][j]=t;
}
}
printf("%d/n",dp[n][k]);
}
return 0;
}
也可以
#include<stdio.h>
#include<algorithm>
using namespace std;
#define Tire(a,b) (a-b)*(a-b)
int a[2005];
int dp[1005][2005];
int main()
{
int N,K,i,j,k,n,t;
while(scanf("%d%d",&N,&K)!=EOF)
{
for(i=1;i<=N;i++) scanf("%d",&a[i]);
sort(a+1,a+N+1);
for(i=0;i<=K;i++)
for(j=0;j<=N;j++) dp[i][j]=0;
for(k=1;k<=K;k++)
for(n=1;n<=N;n++)
{
if(n==k+k){dp[k][n]=dp[k-1][n-2]+Tire(a[n],a[n-1]);continue;}
else
{
dp[k][n]=dp[k][n-1];
if((t=dp[k-1][n-2]+Tire(a[n],a[n-1]))<dp[k][n])dp[k][n]=t;
}
}
printf("%d/n",dp[K][N]);
}
return 0;
}