经典DP问题,先将劳累度排序,相邻相减的平方才是最小的,然后分析:dp[i][j]为前i物品选择了j对最小的疲劳值,对于dp[i][j] 当i = j*2时,则dp[i-2][j-1] + a, 当i>j*2时,dp[i][j] = min(dp[i-1][j], dp[i-2][j-1]+a)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 2000 + 10;
int w[N], dp[N][N/2];
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);
memset(dp, 0, sizeof(dp));
for(int j=1; j<=k; ++j)
{
for(int i=j*2; i<=n; ++i)
{
int a = w[i]-w[i-1]; a *= a;
if(j*2 == i)
dp[i][j] = dp[i-2][j-1] + a;
else
dp[i][j] = min(dp[i-1][j], dp[i-2][j-1] + a);
}
}
printf("%d\n", dp[n][k]);
}
return 0;
}