题目: 很久很久以前,有一位国王拥有5座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人人数也不同。金矿储量与所需工人数量如下表所示:
       如果参与挖矿的工人的总人数是10,每座金矿要么全挖,要么不挖,不能派出一半人挖取一半的金矿。要求用程序求出,要想得到尽可能多的黄金,应该选择挖取哪几座金矿?

编号 黄金储量 所需人数
1 400kg 5
2 500kg 5
3 200kg 3
4 300kg 4
5 350kg 3

解决思路:
       对于每一个金矿都有挖与不挖两种选择,因此可以利用动态规划的思想将总问题逐步分解成若干个子问题,然后得到最优解,具体步骤如下:

1、 寻找状态转移方程式;
状态转移方程式:设金矿数量为n,工人数量为w,金矿的含金量为数组g[],金矿所需开采人数设为数组p[],设F(n,w)为n个金矿、w个工人时的最优收益函数,则状态状态转移方程式为:

  • 问题边界,金矿数为0或工人数为0的情况:F(n,w)=0(n=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])

2、利用状态转移方程式自底向上求解问题;

  • 每一层的求解结果都可以由下层(底层)推导得到,因此可以使用一个表来记录所有已解决的子问题的答案,即而得到最优解,具体看代码实现2

代码实现:
实现1:

  • 最简单的实现方式就是使用递归实现,但是其时间复杂度是O(2^n)
 /*** 获得金矿最优权益* @param w 工人数量* @param n 可选金矿数量* @param p 金矿开采所需的工人数量* @param g 金矿储量* @return  最优收益*/public static int getBestGoldMining(int w,int n,int[] p,int[] g){if(w==0||n==0){return 0;}if (w<p[n-1]){return getBestGoldMining(w,n-1,p,g);}return Math.max(getBestGoldMining(w,n-1,p,g),getBestGoldMining(w-p[n-1],n-1,p,g)+g[n-1]);}

实现2:

 /*** 获得金矿最优权益* @param w 工人数量* @param p 金矿开采所需的工人数量* @param g 金矿储量* @return  最优收益*/public static int getBestGoldMining(int w,int[] p,int[] g){//创建表格int[][] resultTable=new int[g.length+1][w+1];//填充表格for (int i = 1; i <=g.length; i++) {for (int j = 1; j <=w; j++) {if (j<p[i-1]){resultTable[i][j]=resultTable[i-1][j];}else {resultTable[i][j]=Math.max(resultTable[i-1][j],resultTable[i-1][j-p[i-1]]+g[i-1]);}}}//返回最后一个格子的值return resultTable[g.length][w];}

实现3: 对于实现2还可以进行空间上的优化,因为二维数组的每一行的结果都可以由上一行推导得出,因此我们不需要保存整张表格,只保存一行即可,在计算下一行时,进行覆盖替换即可。

 /*** 获得金矿最优权益* @param w 工人数量* @param p 金矿开采所需的工人数量* @param g 金矿储量* @return  最优收益*/public static int getBestGoldMiningV3(int w,int[] p,int[] g){//创建当前结果int[] results=new int[w+1];//填充一维数组for (int i = 1; i <g.length; i++) {for (int j=w;j>=1;j--){if (j>=p[i-1]){results[j]=Math.max(results[j],results[j-p[i-1]]+g[i-1]);}}}//返回最后一个格子的值return results[w];}

动态规划求解金矿问题相关推荐

  1. python实现动态规划求解给定矩阵的和最大的子数组(矩阵中数字正负均存在)

    本篇博文比较简单没有太多实际意义,只是为了练习一下,动态规划我并不熟悉,也是刚处于学习的阶段. 问题: 给定一个指定的矩阵,维数小于1000,在矩阵的所有子数组中寻找具有最大和的子数组求和输出. 思路 ...

  2. 1008-----算法笔记----------0-1背包问题(动态规划求解)

    1.问题描述 给定n种物品和一个背包,物品i的重量是wi,其价值为vi,背包的容量为C.问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大? 2.问题分析 上述问题可以抽象为一个整数规划问 ...

  3. 子串、子数组与子序列类型问题的动态规划求解(Leetcode题解-Python语言)

    一般来说,子串和子数组都是连续的,而子序列是可以不连续的,遇到子序列问题基本上都是用动态规划求解. 53. 最大子数组和(剑指 Offer 42. 连续子数组的最大和) class Solution: ...

  4. python用动态规划求删除路径_Python | 动态规划求解TSP

    解题思路主要有两部分: i为当前节点(城市),S为还没有遍历的节点(城市集合),表示从第i个节点起,经历S集合中所有的点,到达终点的最短路径长度. 回溯找到最优的路径,需要将S集合一一对应一个数字(类 ...

  5. 动态规划求解所有字符的组合数

    一,问题描述 给定若干个字符,求解 这些字符能够表示的最多组合个数.比如{'a','b','c'} 一共有七种组合.(每种组合没有重复的字符 且 组合的种数与顺序无关,如 ab 和 ba 是同一种组合 ...

  6. 使用动态规划求解算法问题的五大特点总结(附基于Python的参考代码)

    什么样的问题应使用动态规划求解 前言 一.求"最"优解问题(最大值和最小值) 1. 乘积最大子数组 问题描述 示例 题目分析 参考代码 2. 最长回文子串 问题描述 示例 题目分析 ...

  7. 01背包问题 动态规划求解方法 动态方程的详细解释 能理解的解释(附python代码)

    01背包问题属于组合优化问题:假设你要出门旅游,你现在有一个书包,这个书包的容量(capacity)有限,有很多物品如牙刷.防晒霜.雨伞.水杯等等,但书包装不下所有物品,因此我们必须有所取舍.那么通常 ...

  8. 动态规划求解多段图问题

    动态规划求解多段图问题(非递归) 问题描述 求解思路 动态规划逆序解法 逆序实现代码 动态规划逆序解法 顺序实现代码 问题描述 如图所示,在A处有一水库,现需要从A点铺设一条管道到E点,边上的数字表示 ...

  9. 数据结构和算法——用动态规划求解最短路径问题

    一.动态规划求解问题的思路     在<算法导论>上,动态规划的求解过程主要分为如下的四步: 描述最优解的结构 递归定义最优解的值 按自底向上的方式计算最优解的值 由计算出的结果构造一个最 ...

  10. C++ 动态规划求解TSP(旅行商问题)

    C++ 动态规划求解TSP(旅行商问题) 动态规划"四部曲" TSP问题介绍 使用动态规划分析TSP 问题结构分析 ==给出问题表示== ==明确原始问题== 递推关系建立 ==分 ...

最新文章

  1. Java面试经典题:线程池的成长之路
  2. Linux学习笔记4-三种不同类型的软件的安装(绿色软件、rpm软件、源代码软件)...
  3. 第四章 Tomcat服务器的安装及配置2
  4. SAP CRM Fiori note automatic delete deletion scenario
  5. Pots POJ - 3414(bfs)
  6. Android Gradle进阶配置指南
  7. 学习 Cesium (五):加载离线高程数据
  8. 如何批量将 Excel 转换为 jpeg、png、bmp 图片
  9. cesium接入加载倾斜摄影(cesium篇.16)
  10. navicat can not load oci dll,193,126
  11. 【iOS】iOS8 与以前版本比较,添加的新特性
  12. Microsoft Recruit in Suzhou Branch (微软苏州招聘)
  13. 兔子生兔子java_用Java编程计算兔子生兔子的问题
  14. 在eclipse部署OpenBravo项目
  15. 修改webbrower中浏览器版本
  16. 实验四 类和对象;类的继承和派生;多态性; 接口;构造器应用
  17. 电子计算机4个发展阶段的划分,计算机以什么划分发展阶段
  18. Qt开发经验总结之武林秘籍
  19. 2022李永乐线性代数
  20. 用python更换桌面壁纸

热门文章

  1. nodejs之koa配置koa-views中间件
  2. Python flag用法
  3. 支付宝小程序: h5跳转 小程序
  4. 常用开发工具及常用DOS命令
  5. 吴伯凡-认知方法论-认知的两重性
  6. 可计算性理论与复杂性介绍
  7. Windows(10) Python polyglot安装和运行失败的问题
  8. vue 实现二维码 vue-qart 和 qrcodejs2
  9. 【Mysql密码管理】-【管理员密码已知、未知(忘记密码)、破解】
  10. hadoop 3.0新特性简单介绍