转载:
/*证明:从4个数中 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;
//先排序,假设从n-1个中选取k对是最少得,那么从n个中选取k对,可以这样分析 对n-1个数 再在末尾增加一个数,那么这个数可能被选中成为k对中其中一对,可能不被选中,如果不被选中,那么从n个中选取k对就相当于从n-1个中选取k对,如果被选中,之前证明了选中的数必须是连续的两个才能事最小,那就相当于从n-2个数中选取k-1对加最后两个数成为,这样,状态转移方程就为dp[i][j]=min(dp[(i-1)][j],dp[(i-)][j-]+(a[i-]-a[i])*(a[i-]-a[i]));
*/
我的AC代码:
#include<cstdlib>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define MAX 2010
int dp[MAX][MAX];
int f[MAX];
int n,k;
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
int i,j;
for( i=;i<=n;i++)
scanf("%d",&f[i]);
sort(f+,f+n+);
memset(dp,,sizeof(dp));
for( i=;i<=n;i++)
for( j=;j<=k&&j*<=i;j++)
if(i==j*) dp[i][j]=dp[i-][j-]+(f[i]-f[i-])*(f[i]-f[i-]);
else
dp[i][j]=min(dp[i-][j],dp[i-][j-]+(f[i]-f[i-])*(f[i]-f[i-]));
cout<<dp[n][k]<<endl;
}
return ;
}