dynamic programming 学习
2015-08-19 16:01
239 查看
这是看到一位大神,写的关于dynamic programming的博客,觉得非常好。简单分析下,然后给出链接。
背景问题就是
有一个国家,所有的国民都非常老实憨厚,某天他们在自己的国家发现了十座金矿,并且这十座金矿在地图上排成一条直线,国王知道这个消息后非常高兴,他希望能够把这些金子都挖出来造福国民,首先他把这些金矿按照在地图上的位置从西至东进行编号,依次为0、1、2、3、4、5、6、7、8、9,然后他命令他的手下去对每一座金矿进行勘测,以便知道挖取每一座金矿需要多少人力以及每座金矿能够挖出多少金子,然后动员国民都来挖金子。
题目补充1:挖每一座金矿需要的人数是固定的,多一个人少一个人都不行。
国王知道每个金矿各需要多少人手,金矿i需要的人数为peopleNeeded[i]。
题目补充2:每一座金矿所挖出来的金子数是固定的,当第i座金矿有peopleNeeded[i]人去挖的话,
就一定能恰好挖出gold[i]个金子。否则一个金子都挖不出来。
题目补充3:开采一座金矿的人完成开采工作后,他们不会再次去开采其它金矿,
因此一个人最多只能使用一次。
题目补充4:国王在全国范围内仅招募到了10000名愿意为了国家去挖金子的人,
因此这些人可能不够把所有的金子都挖出来,但是国王希望挖到的金子越多越好。
题目补充5:这个国家的每一个人都很老实(包括国王),不会私吞任何金子,
也不会弄虚作假,不会说谎话。
题目补充6:有很多人拿到这个题后的第一反应就是对每一个金矿求出平均每个人能挖出多少金子,
然后从高到低进行选择,这里要强调这种方法是错的,如果你也是这样想的,请考虑背包模型,
当有一个背包的容量为10,共有3个物品,体积分别是3、3、5,价值分别是6、6、9,
那么你的方法取到的是前两个物品,总价值是12,但明显最大值是后两个物品组成的15。
题目补充7:我们只需要知道最多可以挖出多少金子即可,而不用关心哪些金矿挖哪些金矿不挖。
那么,国王究竟如何知道在只有10000个人的情况下最多能挖出多少金子呢?国王是如何思考这个问题的呢?
为了更好让自己理解这个问题
先考虑比较简单的三座山的情况
从问题的最后一步入手,就是在要开采第三座金矿时,
如果现在有总人数 n人;
处理函数为f(可用人数,开采前m座金矿),返回数目为前m座金矿的最大可采到的金子。
初始化这些数据
总人数75个人,75<80,没有能力全部开采金矿,
第一次 前3座金矿时
f(75,3)
需要考虑的问题:
1)人数是不是大于开采需求
2)是不是已经到最后一个
用伪代码表示为:
所以
更形象的图为
大神博客链接
http://www.cnblogs.com/sdjl/articles/1274312.html
背景问题就是
有一个国家,所有的国民都非常老实憨厚,某天他们在自己的国家发现了十座金矿,并且这十座金矿在地图上排成一条直线,国王知道这个消息后非常高兴,他希望能够把这些金子都挖出来造福国民,首先他把这些金矿按照在地图上的位置从西至东进行编号,依次为0、1、2、3、4、5、6、7、8、9,然后他命令他的手下去对每一座金矿进行勘测,以便知道挖取每一座金矿需要多少人力以及每座金矿能够挖出多少金子,然后动员国民都来挖金子。
题目补充1:挖每一座金矿需要的人数是固定的,多一个人少一个人都不行。
国王知道每个金矿各需要多少人手,金矿i需要的人数为peopleNeeded[i]。
题目补充2:每一座金矿所挖出来的金子数是固定的,当第i座金矿有peopleNeeded[i]人去挖的话,
就一定能恰好挖出gold[i]个金子。否则一个金子都挖不出来。
题目补充3:开采一座金矿的人完成开采工作后,他们不会再次去开采其它金矿,
因此一个人最多只能使用一次。
题目补充4:国王在全国范围内仅招募到了10000名愿意为了国家去挖金子的人,
因此这些人可能不够把所有的金子都挖出来,但是国王希望挖到的金子越多越好。
题目补充5:这个国家的每一个人都很老实(包括国王),不会私吞任何金子,
也不会弄虚作假,不会说谎话。
题目补充6:有很多人拿到这个题后的第一反应就是对每一个金矿求出平均每个人能挖出多少金子,
然后从高到低进行选择,这里要强调这种方法是错的,如果你也是这样想的,请考虑背包模型,
当有一个背包的容量为10,共有3个物品,体积分别是3、3、5,价值分别是6、6、9,
那么你的方法取到的是前两个物品,总价值是12,但明显最大值是后两个物品组成的15。
题目补充7:我们只需要知道最多可以挖出多少金子即可,而不用关心哪些金矿挖哪些金矿不挖。
那么,国王究竟如何知道在只有10000个人的情况下最多能挖出多少金子呢?国王是如何思考这个问题的呢?
为了更好让自己理解这个问题
先考虑比较简单的三座山的情况
从问题的最后一步入手,就是在要开采第三座金矿时,
如果现在有总人数 n人;
处理函数为f(可用人数,开采前m座金矿),返回数目为前m座金矿的最大可采到的金子。
初始化这些数据
总人数75个人,75<80,没有能力全部开采金矿,
第一次 前3座金矿时
f(75,3)
需要考虑的问题:
1)人数是不是大于开采需求
2)是不是已经到最后一个
用伪代码表示为:
if(是最后一个金矿) { if(人数够开采金矿) return 金矿金子 else return 0; } else //不是最后一个金矿 { if(人数够开采) { 比较 本座金矿金子+f(前n-1座金矿)和 f(前n-1座金矿); return 最大的 } else //不够开采本座 { return f(前n-1座金矿); } }
所以
f(75,3) { return max(f(75,2),f(25,2)+300); } f(75,2) { return max(f(75,1),f(55,1)+110); } f(25,2) { return max(f(25,1),f(5,1)+110); } f(75,1) { return 100; } f(55,1) { return 100; } f(25,1) { return 100; } f(5,1) { return 0; }
更形象的图为
大神博客链接
http://www.cnblogs.com/sdjl/articles/1274312.html
相关文章推荐
- 迅雷快鸟的原理-可能
- ListView刷新指定位置的Item
- poj 1986——Distance Queries
- http post get 区别
- streamflow简介
- 阿里巴巴一道笔试题
- 二分查找(递归和非递归实现)
- 窗口缩小时图片、文字跟着整体缩小
- 纯源码编译安装LAMP,linux,httpd,php,mysql源码编译安装
- 工厂模式
- Aspose.Words使用教程之插入文档元素(二)【连载】
- js仿黑客帝国字母掉落效果代码分享
- 桌面支持--装了系统启动到windows进不去系统--硬盘模式没改
- WebX5 拍照上传功能
- hdu3709 (平衡数) 数位DP
- 防火墙DNAT与SNAT详谈
- 桌面支持--显示驱动程序停止响应,并已恢复 Windows Vista 或 Windows 7 中的错误消息
- 作为码农,我们为什么要写作
- HDU 3746 Cyclic Nacklace(KMP最小循环子串)
- AC自动机模板(数组实现版)