DP。
这题初看就感觉变换下应该比较好做,先排序,然后可以相邻两个数相减,然后求K个不相邻的数的最小和。
后来觉得这个思路不会找K个不相邻数最小和 T T。。
后来PPT上也有讲,找I个物品选K对。
吃饭回来想了下,也不算麻烦。想清楚后开始搞 = =。。发现。。初始化真恶心。
状态转移方程是
dp[k][i] = min(dp[k-1][i-2]+ (a[i]-a[i-1])*(a[i]-a[i-1]), dp[k][i-1]);
表示前 i 个物品,取k对的最小和。
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
using namespace std;
const int MAX = 2010;
int dp[MAX][MAX];
int a[MAX];
int main()
{
int n, K;
while( ~scanf("%d%d",&n,&K) )
{
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
sort(a+1, a+n+1);
int t = 0;
memset(dp,0,sizeof(dp));
for(int i=1; i<=K; i++)
for(int k=i*2; k<=n; k++)
dp[i][k] = INT_MAX;
for(int i=1; i<=2*K; i+=2)
{
t += (a[i+1] - a[i])*(a[i+1] - a[i]);
dp[i/2+1][(i/2+1)*2] = t;
}
for(int k=1; k<=K; k++)
for(int i=2*k+1; i<=n; i++)
dp[k][i] = min(dp[k-1][i-2]+ (a[i]-a[i-1])*(a[i]-a[i-1]), dp[k][i-1]);
printf("%d\n",dp[K][n]);
}
return 0;
}