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

因为考虑到差的平方最小,所以先把物品按重量排序(这样可以使相邻的两个数更加接近从而取得更优的结果)。

dp[i][j]表示i件物品拿j对时最低的疲劳度

i等于2*j时,dp[i][j]=dp[i-2][j-1]+(w[i]-w[i-1])^2

其他情况时(即i大于2*j), dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(w[i]-w[i-1])^2)

View Code
#include <iostream>
#include <algorithm>
using namespace std ;
int dp[2001][1001],w[2001] ;
bool cmp(int a,int b)
{
    return a<b ;
}
int main()
{
    int n,k ;
    while(~scanf("%d%d",&n,&k))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&w[i]) ;
        sort(w+1,w+n+1,cmp) ;
        memset(dp,0,sizeof(dp)) ;
        for(int i=2;i<=n;i++)
            for(int j=1;(j<<1)<=i;j++)
            {
                if(i==(j<<1))
                    dp[i][j]=dp[i-2][j-1]+(w[i]-w[i-1])*(w[i]-w[i-1]) ;
                else 
                    dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(w[i]-w[i-1])*(w[i]-w[i-1])) ;
            }
        printf("%d\n",dp[n][k]) ;
    }
    return 0 ;
}