/*
状态方程:dp[i][j] = min{ dp[i-1][j], dp[i-2][j-1]+(w[i]-w[i-1],2)^2 },0<j*2<=i
其中dp[i][j]表示前i个物品拿j对
在第i个物品的有两种情况,一:第i-1个物品和前面的物品恰好形成j对
二:第i-1个物品没有形成j对,由i-1个物品和第i个物品形成j对
*/
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;
#define N 2000+5
int dp[N][N];
int w[N];
int min(int a,int b){ return a>b?b:a; }
int main()
{
int n,k,i,j;
while(scanf("%d%d",&n,&k)!=EOF)
{
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
scanf("%d",&w[i]);
sort(w+1,w+n+1);
for(i=2;i<=n;i++)
{
for(j=1;j*2<=i;j++)
{
if(j*2==i) dp[i][j] = dp[i-2][j-1]+pow(w[i]-w[i-1],2);
else
dp[i][j] = min(dp[i-1][j],dp[i-2][j-1]+pow(w[i]-w[i-1],2));
}
}
printf("%d\n",dp[n][k]);
}
return 0;
}
HDU-1421:搬寝室
最新推荐文章于 2021-02-24 19:54:28 发布