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增加,类别减少

子问题

  • 静态问题动态化
  • 最简单的情形: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) (n1,m)(n2,m1)(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((n1,m)(n2m1)+(anan1)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 搬寝室(贪心 + 动态规划)的主要内容,如果未能解决你的问题,请参考以下文章

动态规划 hdu 1421 搬寝室

[HDU 1421]搬寝室(富有新意的DP)

hdu1421 搬寝室(dp)

HDU 1421 搬寝室(基础dp)

HDU 1421 搬寝室

hdu 1421 搬寝室(dp)