dynamic programming 学习

来源:互联网 发布:学为贵封闭班 知乎 编辑:程序博客网 时间:2024/06/07 03:18

这是看到一位大神,写的关于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)是不是已经到最后一个

用伪代码表示为:

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

1 0
原创粉丝点击