2011-12-24 12:13:01

地址:http://acm.hdu.edu.cn/showproblem.php?pid=1421

题意:有n样物品,每样物品有重量。要选k对,每对代价是俩物品重量差的平方。问怎么选总代价最小。

mark:排序,然后按顺序dp。

代码:

# include <stdio.h>
# include <stdlib.h>
# include <string.h>


int w[2010], a[2010] ;
int dp[2010][1010] ;


int min(int a, int b){return a<b?a:b;}
int cmp(const void *a, const void *b){return *(int*)a - *(int*)b ;}


int main ()
{
int n, m, k, i, j ;

while (~scanf ("%d%d", &n, &k))
{
for (i = 0 ; i < n ; i++) scanf ("%d", &w[i]) ;
qsort (w, n, 4, cmp) ;
for (i = 1 ; i < n ; i++)
a[i-1] = (w[i]-w[i-1])*(w[i]-w[i-1]) ;

m = n-1 ;
//dp的过程,从a[0...m-1]中选择k个不相邻的
memset (dp, 0x7f, sizeof(dp)) ;
dp[0][0] = dp[1][0] = 0 ;
dp[1][1] = a[0] ;
for (i = 2 ; i <= m ; i++)
{
dp[i][0] = 0 ; //选0个必然是0
for (j = 1 ; j <= k && j <= (i+1)/2 ; j++)
dp[i][j] = min(dp[i-1][j], dp[i-2][j-1]+a[i-1]) ;
}
printf ("%d\n", dp[m][k]) ;
}
}