这题是动态规划。

状态设计:很经典的设计dp[i][j]表示从i个物品中选择j个物品来搬运的最小劳累度,很自然的想到答案便是dp[n][k]。

转移方程:因为疲劳度是关于两个物品的,转移的条件就是i选和不选,假设i不选,那么就是前i-1个选j对,也就是dp[i][j]=dp[i-1][j].假设第i个选,那么这个一定是和前一个组成一对的,为什么?因为这个时候数组是排好序的,相邻的两个数据相差才是最小的,这里是一种贪心的思想。dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]));

边界条件:从0个物品中搬运0件就不累,dp[0][0]=0;

#include<bits/stdc++.h>
using namespace std;
const int N=2010,inf=0x3fffffff;
int n,k,a[N],dp[N][N];
int main()
{
    while(~scanf("%d%d",&n,&k))
    {
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        dp[0][0]=0;
        for(int i=0;i<=n;i++)
            for(int j=1;j<=k;j++)
                dp[i][j]=inf;
        for(int i=2;i<=n;i++)
            for(int j=1;j<=k;j++)
                dp[i][j]=min(dp[i-1][j],dp[i-2][j-1]+(a[i]-a[i-1])*(a[i]-a[i-1]));
        printf("%d\n",dp[n][k]);
    }
    return 0;
}
01-15 20:21