题目地址:点击打开链接
思路:dp[i][j]表示前i个物品取j对的最大值,有2种情况
1.dp[i][j]不包含第i个物品,则dp[i][j]=dp[i-1][j];
2.dp[i][j]包含第i个物品,则第i-1个物品也一定取了,因为第i个物品只能和第i个和第i+1个物品一起取,和第i+1的物品一起取的情况包含在dp[i+1][j]中
AC代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
using namespace std;
int a[2000],dp[2000][1000];
int main()
{
int n,k,i,j;
while(scanf("%d%d",&n,&k) != EOF)
{
for(i=1; i<=n; i++)
{
scanf("%d",&a[i]);
}
sort(a+1,a+n+1);
/*for(i=1; i<=n; i++)
{
for(j=1; j<=k; j++)
{
dp[i][j] = INT_MAX;
}
}*/
//这种赋初值发比较好理解,但是有很多不必的成分,看下面的赋初值的方法
for(j=1; j<=k; j++)
{
for(i=1; i<2*k; i++)
{
dp[i][j] = INT_MAX;
}
}
dp[0][0] = 0;
for(j=1; j<=k; j++)
{
for(i=2*j; i<=n; i++)
{
dp[i][j] = min(dp[i-2][j-1] + (a[i] - a[i-1]) * (a[i] - a[i-1]),dp[i-1][j]);
}
}
printf("%d\n",dp[n][k]);
}
return 0;
}