1.题目描述

有一个国家,所有的国民都非常老实憨厚,某天他们在自己的国家发现了十座金矿,并且这十座金矿在地图上排成一条直线,
国王知道这个消息后非常高兴,他希望能够把这些金子都挖出来造福国民,
首先他把这些金矿按照在地图上的位置从西至东进行编号,
依次为0、1、2、3、4、5、6、7、8、9,然后他命令他的手下去对每一座金矿进行勘测,
以便知道挖取每一座金矿需要多少人力以及每座金矿能够挖出多少金子,然后动员国民都来挖金子。

题目补充说明:

1)挖每一座金矿需要的人数是固定的,多一个人少一个人都不行。国王知道每个金矿各需要多少人手.

2)每一座金矿所挖出来的金子数是固定的.

3)开采一座金矿的人完成开采工作后,他们不会再次去开采其它金矿,因此一个人最多只能使用一次.

详细分析过程看 挖金矿模型

2.测试数据

//分别为挖矿总人数,金矿数

100 5

//下面为详细的挖第i个金矿需要的人数和该金矿对应的金子数

77 92

22 22

29 87

50 46

99 90

3.java实现

import java.util.ArrayList;
//分析见http://www.cnblogs.com/SDJL/archive/2008/08/22/1274312.html
public class digitGold {
public int n;
int max_n=5;//总金矿数
int max_people=100;//总人数
int peopleNeed[]={77,22,29,50,99};
int gold[]={92,22,87,46,90};
//maxGold[i][j]保存了i个人挖前j个金矿能够得到的最大金子数,等于-1时表示未知
public int[][]maxGold=new int[max_people][max_n];
public void init(){for(int i=0;i<max_people;i++){for(int j=0;j<max_n;j++){maxGold[i][j]=-1;}}
}
public  int getMaxGold(int people,int mineNum){int retMaxGold=0;if(people<=0){retMaxGold=0;}else {if(maxGold[people][mineNum]!=-1){retMaxGold=maxGold[people][mineNum];}else if(mineNum==0){//如果只有一个金矿if(people>=peopleNeed[mineNum])retMaxGold=gold[mineNum];elseretMaxGold=0;}else if(people>=peopleNeed[mineNum]){//剩余人数大于挖该金矿人数int g1=getMaxGold(people-peopleNeed[mineNum],mineNum-1)+gold[mineNum];int g2=getMaxGold(people,mineNum-1);retMaxGold=Math.max(g1, g2);}else{//不挖mineNum金矿retMaxGold=getMaxGold(people,mineNum-1);}}maxGold[people][mineNum]=retMaxGold;return retMaxGold;
}
public static void main(String[]args){digitGold d=new digitGold();d.init();int s=d.getMaxGold(99,4);System.out.println(s);}

以上是基于大神的c语言代码用java改写实现的,但是这里有一个问题就是当问题规模足够大时,解空间是无限的,不可能得出一个最优解。这时我们可以通过寻找局部最优解来近似逼近最好解,虽然不是实际解,但是考虑到这样可以保证在有限时间内能求出一个相对较好的解,这也是可以接受的。

4.下面我将用建模的方式来解决问题,即数学思考。(解大规模问题时十分常见)

1)建模:

设能挖出的总金子数为y

g(i)代表第i个金矿挖出的金子数, x(i)代表第i 个金矿挖不挖,x(i)取值为0,1

约束(1)表示挖金矿的人数不能超过总人数这个限制

这个问题就转化为求约束条件下的解,如果问题规模很大时,我们就需要使用模拟退火等一些近似算法来求近似解。

其实这样建模的方式更好理解,但是针对小规模下存在最优解的情况下,需要访问整个解空间,这种方式是比我们上面使用的方式稍微低效一点,不过却是更好理解的。

2). 建模使用的代码如下:

package Server;import java.util.ArrayList;public class GoldModel {public int n;int max_n=5;//总金矿数int max_people=100;//总人数int peopleTotal;int peopleNeed[]={77,22,29,50,99};int gold[]={92,22,87,46,90};//最大金子数public int max=0;//保存挖取最大金子数采用的方案public int maxSeriale[]=new int[5];//生成随机的xi集合,存放随机生成的挖取的方案public ArrayList<String> xs=new ArrayList();//得到给定条件下的总大数,相当于y函数public void getGold(int[]x,int g[],int[] y){int remax=0;remax=getMatrix(x,g);if(remax>max){//满足受限条件if(getMatrix(x,y)<=100){max=remax;maxSeriale=x;}}}//实现数组相乘public int getMatrix(int []x,int[] y){int remax=0;for(int i=0;i<x.length;i++){remax+=x[i]*y[i];}return remax;}
//随机产生一个不重复的方案
public int[] createVariableXi(){for(int i=0;i<=1;i++){for(int j=0;j<=1;j++){for(int k=0;k<=1;k++){for(int h=0;h<=1;h++){for(int g=0;g<=1;g++){//用来去重if(!isContained(i,j,k,h,g))return new int[] {i,j,k,h,g};}}}}}return null;}//判断某方案是否已经出现private boolean isContained(int x,int y,int k,int h,int g){String s=String.valueOf(x)+String.valueOf(y)+String.valueOf(k)+String.valueOf(h)+String.valueOf(g);if(xs.contains(s))return true;xs.add(s);return false;}public static void main(String[] args) {// TODO Auto-generated method stubdigitGold d=new digitGold();d.myMain();}public void myMain(){int []a;///排除全部不挖的情况xs.add("00000");while(null!=(a=createVariableXi())){getGold(a,gold,peopleNeed);}System.out.println("max"+max);System.out.println("seriable"+maxSeriale[0]+"--"+maxSeriale[1]+"--"+maxSeriale[2]+"--"+maxSeriale[3]+"--"+maxSeriale[4]);}
}
执行结果:
max133
seriable0--0--1--1--0

5.总结

下面我准备将我们现有的问题规模变大,使得解空间近似与无限大,这时可以体现出使用建模来解决问题的思维方式.我们可以使用模拟退火等方法求近似解。

动态规划之挖金矿(背包问题)相关推荐

  1. 【动态规划模型】金矿模型理解动态规划!(精彩的故事)

    对于动态规划,每个刚接触的人都需要一段时间来理解,特别是第一次接触的时候总是想不通为什么这种方法可行,这篇文章就是为了帮助大家理解动态规划,并通过讲解基本的01背包问题来引导读者如何去思考动态规划.本 ...

  2. 动态规划的用法——01背包问题

    动态规划的用法--01背包问题 问题主题:著名的01背包问题 问题描述: 有n个重量和价值分别为wi.vi的物品,现在要从这些物品中选出总重量不超过W的物品,求所有挑选方案中的价值最大值. 限制条件: ...

  3. 【动态规划】0/1背包问题

    问题 H: [动态规划]0/1背包问题 时间限制: 1 Sec  内存限制: 64 MB 提交: 152  解决: 95 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼和李旭 ...

  4. 动态规划——物品无限的背包问题

    动态规划--物品无限的背包问题 物品无限的背包问题.有nn种物品,每种均有无穷多个.第i种物品的体积为ViV_i,重量为WiW_i.选一些物品装到一个容量为CC的背包中,使得背包内物品在总体积不超过C ...

  5. 【动态规划】P1048 01背包问题:采药

    时间对应容量,用01背包 [动态规划笔记]01背包问题及优化_m0_52043808的博客-CSDN博客 代码: #include<iostream> using namespace st ...

  6. vs2017\vs2019 动态规划算法实现0-1背包问题 C

    这是针对于博客vs2017安装和使用教程(详细)和vs2019安装和使用教程(详细)的动态规划算法实现0-1背包问题的示例 目录 一.问题描述

  7. 动态规划:关于01背包问题 I

    动态规划:关于01背包问题,你该了解这些! 对于面试的话,其实掌握01背包,和完全背包,就够用了,最多可以再来一个多重背包. 如果这几种背包,分不清,我这里画了一个图,如下: 至于背包九讲其其他背包, ...

  8. 动态规划-如何求解金矿问题

    参考书籍 <漫画算法-小灰的算法之旅>5.11 问题描述 假设现在有5座金矿,每座金矿的黄金存储量不同,需要参入挖掘的工人人数也不同.要求:参入挖矿的工人的总数是10.每座金矿要么全挖,要 ...

  9. java经典问题国王_动态规划-国王的金矿问题java

    紧接着上一篇动态规划问题,现在我们开始探讨一个新的问题,问:有一个发现了5个金矿,每一个金矿的储量不同,需要参与挖掘的工人数也不通,参与挖矿工人的总数量是10人,每一座金矿要么全挖,要么不挖,不能派一 ...

  10. 编程实现背包的递归和非递归两种解法_算法动态规划(七)背包问题4

    ⚠️今天继续我们来探讨背包问题中的完全背包问题.完全背包:N个物品,容量为V,每个物品可以无限次使用,求达到V的最值. ???今日练习(一)零钱兑换(LeetCode-322).给定一批硬币coins ...

最新文章

  1. matlab gui优化,matlabgui优化程序
  2. WIN7移动硬盘格式化问题RAW格式读取 XP移动硬盘读取异常分析 移动硬盘格式不兼容...
  3. 岗位推荐 | 微软AI Research Group招募自然语言处理AI算法研究实习生
  4. hdu 5521 Meeting(最短路)
  5. dotNET Core 3.X 使用 Autofac 来增强依赖注入
  6. 实现链栈的各种基本运算的算法_LeetCode基础算法题第78篇:如何不用加减号实现两数的加法运算?...
  7. 熟悉MyEclipse
  8. 红橙Darren视频笔记 换肤框架1 获取其他apk中的资源
  9. java位运算和字节编码(一)
  10. unity三维地图的经纬度如何在二维地图上表示_安全数据分析:数据点—地图—线性回归...
  11. Javaweb项目在线学习平台系统(Spring+SpringMVC+MyBatis)
  12. Apache ab测试解析
  13. 猿创征文|人工智能啾养成之路 - 写代码三天,CSDN治好了我的精神内耗
  14. gcd euclid_使用EUCLID的算法找到两个数字的GCD(最大公约数)
  15. 项目经理如何处理中途接手的项目
  16. k8s跑一个nginx-app体验
  17. Java处理富文本编辑器的图片转为base64编码
  18. SeekBarVolumizer.java
  19. fwrite和fread函数的用法小结
  20. 我的世界1.12.2 神奇宝贝(精灵宝可梦) 开服教程

热门文章

  1. python 按比例缩小图片
  2. python面向对象编程指南 豆瓣_Python面向对象编程
  3. JavaScript|表格背景颜色改变页面
  4. 计算机软件如何永久删除,如何彻底删除电脑软件
  5. linux字符串替换命令,Linux使用sed命令替换字符串教程
  6. 实验十七 通信录csv文件管理
  7. 2021年图扑软件重点事件回顾
  8. AI公司盈利难?MSN聊天机器人起家的小i是如何做到的
  9. 小心!QQ和MSN聊天记录也会随时被监控
  10. 七月算法-P2 概率论与数理统计(1)