金矿问题

问题概述:
有一位国王拥有5座金矿,每座金矿的黄金储量不同,
需要参与挖掘的工人人数也不同。例如有的金矿储量是500kg黄金,需 要5个工人来挖掘;有的金矿储量是200kg黄金,需要3个工人来挖 掘…… 如果参与挖矿的工人的总数是10。每座金矿要么全挖,要么不挖,不能 派出一半人挖取一半的金矿。要求用程序求出,要想得到尽可能多的黄 金,应该选择挖取哪几座金矿?
什么是动态规划:
动态规划:将复杂问题简化为规模较小的子问题,再从简单的子问题自底向上一步一步递推,最终得到复杂问题的最优解
思路:
利用动态规划思想将大问题拆分为一个个小问题,之后一步一步解决问题
例:

如此直至人数为0或者剩余金矿数为0,也就是问题的边界
之后自底向上就可以从小问题的最优解求出整体的最优解,使利益最大化
具体解释与步骤详情参考代码

package algorithm;/*** 动态规划金矿问题* 如何在已有人数和金矿收益情况下获得最大的淘金收益*  动态规划:将复杂问题简化为规模较小的子问题,*      再从简单的子问题自底向上一步一步递推,最终得到复杂问题的最优解*  动态规划的要点:*      确定全局最优解与最优子结构间的关系*      确定问题的边界*/
public class GoldMining {public static void main(String[] args) {int w = 10;int[] p = {5,5,3,4,3};int[] g = {400,500,200,300,350};System.out.println("最优收益为:"+getBestGoldMining(g.length,w,p,g));System.out.println("最优收益为:"+getBestGoldMining2(g.length,w,p,g));System.out.println("最优收益为:"+getBestGoldMining3(g.length,w,p,g));}/*** 此方法采用递归方式计算每种最优子结构的收益情况,递归到问题的边界即可用人数为0,或者剩余矿数为0* 缺点:*  会进行许多的重复计算,每次都分2种最优子结构,时间复杂度为O(2^n)* @param n 总金矿数* @param w 总可用人数* @param p 每个金矿需要人数* @param g 每个金矿的收益*/public static int getBestGoldMining(int n,int w,int[] p,int[] g){if(w==0 || n==0){return 0;}//如果当前可用人数不足以挖当前矿,则换个矿,n-1代表当前矿if(w<p[n-1]){return getBestGoldMining(n-1,w,p,g);}/*** 如果当前矿可以挖,则选取两个最优子结构(挖当前矿,不挖当前矿)中收益高的方法* n-1 代表除去当前矿,去后一个矿查看* w-p[n-1] 代表挖当前矿后剩下的人数*/return Math.max(getBestGoldMining(n-1,w,p,g),(getBestGoldMining(n-1,w-p[n-1],p,g)+g[n-1]));}/***  根据自底向上求解的步骤,采用一张表记录计算结果,避免重复计算*  时间与空间复杂度都是O(n*w)* @param n* @param w* @param p* @param g*/public static int getBestGoldMining2(int n,int w,int[] p,int[] g){//使用二维数组表示表,纵轴是金矿信息,横轴是人数信息int[][] resultTable = new int[n+1][w+1];//填充表格for (int i = 1; i <= n; i++) {for (int j = 1; j <= w; j++) {//当前人数不足以挖g[i-1]矿,就把获得收益置为不挖当前矿的收益if(j<p[i-1]){resultTable[i][j] = resultTable[i-1][j];}else{/*** 可以挖当前矿,取挖矿与不挖矿的最优解* resultTable[i][j]就代表当前矿的最大收益 = max(不挖当前矿去查看之后的收益,挖当前矿查看之后的收入并加上当前矿的收入)* 为什么resultTable[i][j]后面的却是resultTable[i-1][j-p[i-1]]+g[i-1]* 因为当前循环是从1开始的,g中的i-1、p中的i-1都其实代表的是当前矿的信息*/resultTable[i][j] = Math.max(resultTable[i-1][j],resultTable[i-1][j-p[i-1]]+g[i-1]);}}}//最后一个格子就是最优收益return resultTable[g.length][w];}/*** 以上方法的空间复杂度仍有可以优化的余地* 根据Math.max(resultTable[i-1][j],resultTable[i-1][j-p[i-1]]+g[i-1]);我们可以发现我们当前的最优解都是根据上一行推导而来* 故我们可以只用一行表格来代替整个表格,可以看出每次都是i-1使用左边的数据,所以我们从右边替换数据即可* 以下代码我们相当于明面只保留了人数的横坐标,实际用两重for循环保证了还是二维的表格,只是节省了空间*/public static int getBestGoldMining3(int n,int w,int[] p,int[] g){int[] resultTable = new int[w+1];for (int i = 1; i <= n; i++) {for (int j = w; j >=1; j--) {if(j>=p[i-1]){//左边的resultTable[j]是i号金矿时的收益,而右边则相当于是i-1号矿收益因为还未被覆盖resultTable[j] = Math.max(resultTable[j],resultTable[j-p[i-1]]+g[i-1]);}}}return resultTable[w];}
}

动态规划经典例题-国王的金矿问题相关推荐

  1. ヾ(o◕∀◕)ノヾ各种动态规划经典例题(新手向、多类型)

    ヾ(o◕∀◕)ノヾ各种动态规划经典例题(新手向.多类型) 一.前言 ヾ(・ω・`。)我把比较常见的类型的动态规划找了一些经典的例题,适合作为新手的入门例题,用于帮助我们对各种不同的动态规划有所了解,很 ...

  2. 动态规划入门之国王的金矿

    最近学习算法,对动态规划不太了解,使用的时候照搬转移方程式,知其然不知其所以然,今天看到一篇动态规划的教程,解释得非常通俗,原文在这里[动态规划入门教程] (http://blog.csdn.net/ ...

  3. 运筹说 第69期 | 动态规划经典例题讲解

    通过前几期的学习,我们已经学会了动态规划的基本概念和基本原理,并且掌握了动态规划模型的建立和具体的求解方法,本期小编带大家学习动态规划在经济管理中的应用. 除了前面讲到的最优路径.资源分配问题外,动态 ...

  4. 动态规划学习-【国王和金矿】

    微信公众号 题目: 有一个国家发现了5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人数也不同.参与挖矿工人的总数是10人.每座金矿要么全挖,要么不挖,不能派出一半人挖取一半金矿.要求用程序求解出, ...

  5. 动态规划简单例子——国王与金矿(c++)

    动态规划的要点:确定全局最优解和最优子结构之间的关系,以及问题的边界.以数字的形式表达就是状态转移方程式.下面以一个例子来对他们进行描述. 问题描述: 有一个国家发现了5座金矿,每座金矿的黄金储量不同 ...

  6. 动态规划经典例题:乘积最大连续子数组

    题目: 输入一个整形数组,数组里有正数也有负数.数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值.例如数组:arr[]={1, 2, 3, -2, 4, -3 ...

  7. 动态规划经典例题:钢条切割

    一.递归算法 如果在第i个地方切割,就把钢条分为两个长度为i,n-i的钢条,问题转化为求这切割两个钢条的最大价值之和 考虑到不切割时的价值 只要比较不切割时的价值和所有切割情况价值和的最大值即可 递归 ...

  8. 动态规划经典例题解析

    一.不同路径问题 题目描述 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为"Start" ). 机器人每次只能向下或者向右移动一步.机器人试图达到网格的右下角 ...

  9. 数字三角形(动态规划经典例题)

    资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 (图3.1-1)示出了一个数字三角形. 请编一个程序计算从顶至底的某处的一条路 径,使该路径所经过的数字的总和最大. ●每一步可沿左斜 ...

最新文章

  1. 在javascript中判断类型
  2. 2018-3-14智能算法(文章--优化问题的智能算法及其哲学内涵)笔记一(什么是优化问题)
  3. Geoderma:南土所梁玉婷组-施用粪肥土壤中抗生素抗性基因和金属抗性基因的共存机制...
  4. 层次遍历二叉树(编程之美3.10)
  5. CSMA/CD--CSMA/CA
  6. 你有没有想过你的上级为什么让你干这件事情,他想干什么
  7. 每天数十亿次请求的应用经验分享,值得参考!
  8. DockerCompose-初始Compose
  9. bartlett 算法 matlab,GWO(灰狼优化)算法MATLAB源码逐行中文注解(转载)
  10. 2019年1月已到,Java 8 要收费了吗?
  11. iOS-常用的第三方框架的介绍
  12. java keypad game,关于java:Custom Keypad – 如何使这些按钮正常工作?
  13. Unity3D实践4:带有出入特效的提示框
  14. ASPNetCore MVC ModelValidation-ajax
  15. 2022-2027年(新版)中国数字出版行业发展动态与未来前景趋势报告
  16. Zotero英文翻译插件安装教程
  17. pandas分析NBA2017-2018赛季球员球队数据
  18. 图像去噪(阿尔法均值滤波器)
  19. 华为新机预装鸿蒙,华为后续新机直接预装鸿蒙OS:Mate 40 Pro 4G版或首发
  20. PV(访问量)、UV(独立访客)、IP(独立IP) (转)

热门文章

  1. 使用CobaltStrike制作宏文件钓鱼
  2. 真给 IT 人丢脸啊!看完我直接蚌埠住了!
  3. 报错:ch.qos.logback.core.joran.spi.JoranException
  4. 音视频探索(2):AAC编码解析
  5. 红孩子VS腾讯合作项目,API对接被评为腾讯优秀案例
  6. leetcode 789. 逃脱阻碍者
  7. Java+JSP基于ssm广州市家教中介服务网站-计算机毕业设计
  8. war包还原成项目_反编译 war 包成传统项目的方法
  9. 极路由3与存储的适配规划
  10. iOS 修改键盘的return键