/******************
证明:假设四个从小到大的数: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
///要点1:所以排序之后如果要取重量差的平方最小,只能在相邻元素中取,每相邻两个元素取一次
///要点2:由于只用到n-2,n-1,n的关系,所以可以用滚动数组解决,开的数组为dp[3][2005]
///
******************/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;
int dp[3][2005];
int a[2000];
int main()
{
int n,k;
int i,j;
while(scanf("%d%d",&n,&k)!=EOF)
{
for(i=1;i<=n;++i)scanf("%d",&a[i]);
sort(a+1,a+n+1);
memset(dp,0,sizeof(dp));
for(i=2;i<=n;++i)
{
for(j=1;j*2<=i&&j<=k;++j) //条件重要
{
if(j*2<i)
{
dp[i%3][j]=min(dp[(i-1)%3][j],dp[(i-2)%3][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]));
}
else if(j*2==i)
dp[(i)%3][j]=dp[(i-2)%3][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]);
}
}
printf("%d\n",dp[n%3][k]);
}
return 0;
}
HDOJ 1421 搬寝室
最新推荐文章于 2019-01-20 13:15:30 发布