HDU 1421 搬寝室(贪心 + 动态规划)
Posted jpphy0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1421 搬寝室(贪心 + 动态规划)相关的知识,希望对你有一定的参考价值。
题目
搬寝室 - http://acm.hdu.edu.cn/showproblem.php?pid=1421
分析
引导
在2 5 9 76 8 56 19 24 34 6共10个数中任选6个数分成3组,例如:(2, 8)、 (6, 24)、(56, 19) ,有无使得3组数据的差的平方和更小的方案?
- 2 5 6 8 9 19 24 34 56 76
- 2 5 6 8 9 19 24 34 56 76
- 2 5 6 8 9 19 24 34 56 76
【贪心:排序后取相邻的数成为一个分组易得更优方案】 - 2 5 6 8 9 19 24 34 56 76
- 2 5 6 8 9 19 24 34 56 76
- 2 5 6 8 9 19 24 34 56 76
取1组的方案?
- 方案数:9
- (1,2)、(2,3)、(3,4)、(4,5)、(5,6)、(6,7)、(7,8)、(8,9)、(9,10)
取2组的方案?
- 方案数及分类:7+6+5+4+3+2+1
- 按第1组的位置分类 —— 到哪里去?
- (1,2)、[(3,4)、…、(9,10)]
- (2,3)、[(4,5)、…、(9,10)]
- (3,4)、[(5,6)、…、(9,10)]
- (4,5)、[(6,7)、…、(9,10)]
- (5,6)、[(7,8)、…、(9,10)]
- (6,7)、[(8,9)、…、(9,10)]
- (7,8)、[(9,10)]
- 若增加一个物品,改变所有类
- 按2组的位置分类 —— 从哪里来?
- [(1,2)]、(3,4)
- [(1,2)、(2,3)]、(4,5)
- [(1,2)、…、(3,4)]、(5,6)
- [(1,2)、…、(4,5)]、(6,7)
- [(1,2)、…、(5,6)]、(7,8)
- [(1,2)、…、(6,7)]、(8,9)
- [(1,2),…,(7,8)]、(9,10)
- 若增加一个物品,将增加一类
取3组的方案?k组呢?
- 按第1、第2组的位置分类 —— 到哪里去?
- 初始状态共28个,可分28类
- 随k增加,类别更多
- 按第3组的位置分类 —— 从哪里来?
- 共5类
- [……]、(5,6)
- [……]、(6,7)
- [……]、(7,8)
- [……]、(8,9)
- [……]、(9,10)
- 随k增加,类别减少
- 共5类
子问题
- 静态问题动态化
- 最简单的情形:2个物品取1组
- 次简单的情形:3个物品取1组、4个物品取1组、……(注意:包含关系)
- 稍复杂的情形:4个物品取2组、5个物品取2组、……(注意:包含关系)
- ……
- 复杂情形能根据简单情形推导吗?
- 能,n个物品取m组的最优解可以根据 n-1个物品取m组的最优解和n-2个物品取m-1组的最优解推导。
- ( n − 1 , m ) 和 ( n − 2 , m − 1 ) → ( n , m ) (n-1,m)和(n-2,m-1) \\rightarrow (n,m) (n−1,m)和(n−2,m−1)→(n,m)
- 方 程 : ( n , m ) = m a x ( ( n − 1 , m ) , ( n − 2 , m − 1 ) + ( a n − a n − 1 ) 2 ) 方程: (n,m) = max\\left((n-1,m),(n-2,m-1)+ (a_n - a_{n-1})^2 \\right) 方程:(n,m)=max((n−1,m),(n−2,m−1)+(an−an−1)2)
- 每一个子问题都是一次贪心 —— 分阶段分类贪心
最优解递推过程
代码【78MS】
#include <bits/stdc++.h>
using namespace std;
#define MXN 2010
#define INF 0x7fffffff
int n, k, a[MXN], dp[MXN];
int main() {
while (cin >> n >> k) {
for(int i = 1; i <= n; i++) scanf("%d", a+i);
sort(a+1, a+n+1);
memset(dp, 0, sizeof dp);
dp[0] = INF;
for(int i = 1; i <= k; i++){
for(int j = 1; j <= n+2-2*k; j++){
dp[j] = min(dp[j-1], dp[j]+(a[2*i-2+j]-a[2*i+j-1])*(a[2*i-2+j]-a[2*i+j-1]));
}
}
cout << dp[n+2-2*k] << endl;
}
return 0;
}
以上是关于HDU 1421 搬寝室(贪心 + 动态规划)的主要内容,如果未能解决你的问题,请参考以下文章