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. C语言编写的PHP框架--yaf入门编程
  2. android 电视安装apk文件损坏,android - 无法在Android电视盒上安装APK - 堆栈内存溢出...
  3. Transformer可以不需要Softmax?Kakao提出了UFO-ViT,性能高,计算量还小
  4. SQL优化笔记(二)—CPU优化
  5. [礼仪大赛常识]酒店客房服务礼仪
  6. VC++中轻松实现滑动(Slider)控件
  7. [19保研]四川大学网络空间安全学院 关于举办2018年优秀大学生暑期夏令营的通知...
  8. 主板检测卡c5_电脑主板检测卡的代码是什么意思_电脑主板故障诊断检测卡代码汇总(5)_飞翔教程...
  9. ubuntu16.04部署开源看板项目wekan(非docker部署)
  10. c4d如何把文字贴在物体表面_C4D立体贴地面字基础知识点
  11. php theexcerpt,wordpress使用the_excerpt函数显示文章的摘要信息
  12. Excel数据透视,日期最大值或最小值显示为0
  13. 讯飞AIUI智能机器人1
  14. Unity学习笔记:Animator、Animator Controller、Animation Cilp之间的关系、以及Blend Tree的用法;
  15. python 模拟键盘自动打字敲英语文章
  16. 安卓微信8.0.22 正式版,5个隐秘改变你发现了吗?
  17. Apple Car将提前“出世”,华为、百度准备好了吗?
  18. 苹果手机怎么编辑word文档_Word文档怎么转化为pdf格式?办公必备方法!
  19. 2022-2028年版中国类金融行业发展走势与投资风险评估报告
  20. 图像的点云拼接-原理讲解与代码实现

热门文章

  1. 今日股市板块利好早知道,全球科技巨头聚齐联手保护云数据
  2. 计算机上图片打不开,电脑上打不开jpg格式的图片是怎么回事?
  3. window远程桌面无法复制粘贴文件到本地
  4. css shine_什么是Shine Enterprise Java模式?
  5. 利用 UPnP 的反射攻击分析
  6. python猜数游戏续_python实现猜数游戏
  7. 不小心把移动硬盘设置为活动分区后的解决方法
  8. VBA 获取某列最后非空单元格的行数
  9. 电容在电路中的几种作用
  10. 如何用计算机算分组数据方差,『分组数据如何Excel计算标准差』Excel表格求分组数据的方差...