LeetCode题解:如何求解金矿问题(动态规划)

这篇博客探讨了如何利用动态规划算法解决一个金矿挖掘的问题,其中涉及到如何优化资源分配以获得最大收益。首先介绍了贪心算法的思路,然后详细解释了动态规划的方法,包括确定最优解和子结构的关系、状态转移方程式的建立,以及自底向上的求解过程,并给出了代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

很久很久以前,有一位国王拥有5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人人数也不同。例如有的金矿储量是500kg黄金,需要5个工人来挖掘:有的金矿储量是200kg黄金,需要3个工人来挖掘…

如果参与挖矿的工人的总数是10。每座金矿要么全挖,要么不挖,不能派出一半人挖取一半的金矿。要求用程序求出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?

总共10个工人,A:400kg黄金/5人 B:500kg黄金/5人 C:200kg黄金/3人 D:300kg黄金/4人 E:350kg黄金/3人

n/w 1个工人 2个工人 3个工人 4个工人 5个工人 6个工人 7个工人 8个工人 9个工人 10个工人
400kg黄金/5人
500kg黄金/5人
200kg黄金/3人
300kg黄金/4人
350kg黄金/3人
  • 解决方法

    1. 贪心算法:依次求得局部最优解,最终得到全局最优解

      1. 按照金矿的性价比从高到低进行排序,有限选择性价比最高的金矿来挖掘,然后选择性价比第2的…
      2. 按照贪心算法的思路得出来的最佳金矿收益是350+500即850kg黄金
        == 按照这种想法是局部最优,但是全局未必是最优的
    2. 动态规划:把复杂的问题简化成规模较小的子问题,再从简单的子问题自底向上一步一步递推
      动态规划的要点:确定全局最优解和最优子结构之间的关系,以及问题的边界

      原问题分解成子问题进行求解(类似于背包问题

  • 动态规划的状态转移方程式

    我们把金矿数量设为n,工人数量设为w,金矿的含金量设为数组g[ ],金矿所需开采人数设为数组p[ ]. 设F(n, w)为n个金矿、w个工人时的最优收益函数,那么状态转移方程式如下。

    F(n,w) = 0 (n=0或w=0)

    问题边界,金矿数为0或工人数为0的情况。

    F(n,w)= F(n-1,W) (n≥1, w<p[n-1])

    当所剩工人不够挖掘当前金矿时,只有一种最优子结构。

    F(n,w) = max(F(n-1,w), F(n-1,w-p[n-1])+g[n-1]) (n≥1, w≥p[n-1])

    在常规情况下,具有两种最优子结构(挖当前金矿或不挖当前金矿)。

  • 相同的颜色代表了方法被传入相同的参数
    在这里插入图片描述

  • 自底向上求解

w < p[n-1] : F(n,w)= F(n-1,W) (n≥1, w<p[n-1])
w ≥ p[n-1] : F(n,w) = max(F(n-1,w), F(n-1,w-p[n-1])+g[n-1])

例如:F(2,10) = max(F(2-1,10),F(2-1,10-5)+500) = max(F(1,10),F(1,5)+500) = max(400,400+500) = 900

n/w 1个工人 2个工人 3个工人 4个工人 5个工人 6个工人 7个工人 8个工人 9个工人 10个工人
400kg黄金/5人 0 0 0 0 400 400 400 400 400 400
500kg黄金/5人 0 0 0 0 500 500 500 500 500 900
200kg黄金/3人 0 0 200 200 500 500 500 700 700 900
300kg黄金/4人 0 0 200 300 500 500 500 700 800 900
350kg黄金/3人 0 0 350 350 500 550 650 850 850 900
  • 代码实现
package some_problem;
/**
 * Copyright (C), 2019-2020
 * author  candy_chen
 * date   2020/7/30 16:00
 * version 1.0
 * Description: 测试
 */

/**
 *
 */
public class GetBestGoldMining {
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值