/*
可以说是背包问题吧:背包容量为k组,从n个中挑k组
因为要平方差最小的,故配组的时候一定是相邻的两个,共有n-1组,求出每组的平方差
所求就变成了从n-1个数中跳k个和最小的(好像挺简单,但是不能把同一个物品搬两次吧,
求相邻的两个数的平方差的时候,除了头尾,其余物品都算了两次)
所以用动态规划
*/
#include<stdio.h>
#include<algorithm>
using namespace std;
#define Min(a,b) ((a)<(b)?(a):(b))
int d[2005][1005],dat[2005];
int n,k;
void dp()
{
int i,j;
memset(d,127,sizeof(d));
for(i=0;i<=n;i++)
d[i][0]=0;
for(i=2;i<=n;i++)
for(j=1;j*2<=i;j++)
d[i][j]=Min(d[i-1][j],d[i-2][j-1]+dat[i-1]);//若是选当前这组(i和i-1的平方差存在dat[i-1]),
//则dat[i-1](当前i和i-1的平方差)+d[i-2][j-1](在i-1中挑j-1组,保证了不会挑重物品)
}
int main()
{
int i;
while(scanf("%d%d",&n,&k)!=-1)
{
for(i=1;i<=n;i++)
scanf("%d",&dat[i]);
sort(dat+1,dat+n+1);
for(i=1;i<n;i++)
dat[i]=(dat[i]-dat[i+1])*(dat[i]-dat[i+1]);
dp();
printf("%d\n",d[n][k]);
}
return 0;
}
hdu 1421 搬寝室--类背包问题
最新推荐文章于 2020-03-26 17:19:25 发布