您的位置:首页 > 其它

HDU_1421 搬寝室 【dp】

2018-03-04 10:11 281 查看
题目链接

题目描述

给定n个物品,每个物品有重量,

从中选出m对,使得这m对物品重量差的平方和最小。

疲劳度:m对物品重量差的平方和

解题思路

将物品按质量递增排序后,从前i件物品中拿走j对
(j*2<=i)
时,(1)不拿第i件,则
dp[i][j]=dp[i-1][j]
,这个毫无疑问。(2)拿第i件物品,则第i件物品肯定和第i-1件物品一起拿,则
dp[i][j]=(a[i]-a[i-1])*(a[i]-a[i-1])+dp[i-2][j-1]
,即从前i-2件中拿j-1对的疲劳值加上拿了最后两件物品的疲劳值(当然,由前到后处理的,i和j前面的所有情况都已经处理好了,都是最小值)。

状态转移方程:
dp=min((1),(2)=dp[i][j]=min(dp[i-1][j],(a[i]-a[i-1])*(a[i]-a[i-1])+dp[i-2][j-1]);。


代码部分

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#define inf 0x3f3f3f3f3f
using namespace std;
const int maxn = 2e3 + 10;
int n, k;
int dp[maxn][maxn], a[maxn];
int main()
{
while(cin >> n >> k)
{
for(int i = 1; i <= n; ++ i)
cin >> a[i];
sort(a + 1, a + n + 1);
memset(dp, inf, sizeof(dp));
for(int i = 0; i <= n; ++ i)
dp[i][0] = 0;
for(int i = 2; i <= n; ++ i)
{
for(int j = 1; j * 2 <= i && j <= k; ++ j)
{
dp[i][j] = min((a[i] - a[i - 1]) * (a[i] - a[i - 1]) + dp[i - 2][j - 1], dp[i - 1][j]);
}
}

cout<<dp
[k]<<endl;

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: