题意:n个物品,要搬走k对,每次搬两个,每次产生的疲劳为两个物品重量之差的平方
首先要明白一点:n个物品中取的k对,每对中两个物品的重量肯定是按排序相邻的。所以要先排序,
1、dp[i][j]表示前i个物品中选j对产生的最小疲劳度,
2、状态转移:对第i个物品有两种情况,选或者不选
如果选,状态转移到dp[i-2][j-1]
如果不选,状态转移到dp[i-1][j]
状态转移方程 dp[i][j] = min(dp[i-1][j], dp[i-2][j-1] + (a[i]-a[i-1])*(a[i]-a[i-1]) )
3、初始化问题:i < 2*j 时,dp[i][j] = oo
j = 0时,dp[i][j] = 0
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>
#define N 2005
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
#define P system("pause")
using namespace std;
int a[N],dp[N][N/2];
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int n,k;
while(scanf("%d%d",&n,&k) != EOF)
{
int i, j;
for(i = 1 ; i <= n; i++)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
memset(dp,0,sizeof(dp));
for(i = 1; i <= n; i++)
for(j = i/2+1; j <= n/2; j++)
dp[i][j] = inf;
for(i = 2; i <= n; i++)
for(j = 1; j <= i/2 && j<= k; j++)
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;
}