#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define inf 0x0f0f0f0f
#define LL long long
/************************************************
designer:hl
time:2016/11/15
Exe.Time:405 ms
Exe.Memory:9440 KB
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1421
题意:亲切中文题
题解:经典dp 判断前i个取k对的最优解
思考如果在前i个取j对的情况有两种
第一种是去第i个 那么肯定要取第i-1个与之配对
第二种是不取第i的
那么最优值就从这两种中取得
第一种是取得i和i-1这一对 并且加上前i-2个取j-1对
第二种就直接是不取 直接等于前i-1个取j对
就直接得到动态规划方程 min(dp[i - 1][j - 2] + (data[j] - data[j - 1]) * (data[j] - data[j - 1]), dp[i][j - 1])
************************************************/
using namespace std;
int dp[1005][2005];
int main() {
int data[2005];
int n, i, j, k, l, t, count, num;
while (~scanf("%d%d", &n, &k)) {
for (i = 1; i <= n; i++) {
scanf("%d", &data[i]);
}
memset(dp, 0, sizeof(dp));
sort(data + 1, data + 1 + n);
//前j个取i对
for (i = 1; i <= k; i++) {
for (j = 2 * i; j <= n; j++) {
int temp = (data[j] - data[j - 1]) * (data[j] - data[j - 1]);
//如果刚好全部取完,那么肯定要全部取完咯
if (j == 2 * i) {
dp[i][j] = dp[i - 1][j - 2] + temp;
} else {
dp[i][j] = dp[i - 1][j - 2] + temp < dp[i][j - 1] ? dp[i - 1][j - 2] + temp : dp[i][j - 1];
}
}
}
printf("%d\n", dp[k][n]);
}
return 0;
}
hdu 1421 搬寝室 dp
最新推荐文章于 2022-08-11 17:24:34 发布