“01背包问题”描述
一个网站管理员,工作目标是在保证不被查水表的前提下尽可能吸引更多的流量。
他拥有的资源类型、各自的猎奇度和危险程度如下:
资源类型 | 动漫 | 八卦 | 军事 | 花边 | 政治 |
---|---|---|---|---|---|
猎奇度 | 5 | 3 | 8 | 4 | 10 |
危险程度 | 2 | 1 | 8 | 5 | 6 |
假设网站最高能承受的危险程度之和为18点,他该如何选择网站资源才能使得网站猎奇度最高?
解决思路
01背包问题是动态规划算法的经典例题之一。解题思路如下:
先从最后一个资源开始考虑,该管理员可以将“政治”挂在网站上,也可以不挂。为了决定挂不挂,他准备让手下甲和乙去做这么两件事:
-
甲去计算并向管理员报告:如果不挂“政治”,只考虑前四种资源,网站最高能达到的猎奇度加上之前已经挂上的资源的猎奇度(目前为0)是多少;
-
然后管理员判断了一下现有危险程度容量是否足够挂“政治”资源,如果不够,则不给乙布置任何任务。如果够,则让乙去计算挂上“政治”后,考虑前四种资源,网站剩余的(18-6=12点)危险程度容量能达到的最高猎奇度加上之前已经挂上的资源的猎奇度(目前只有”政治“)一共是多少。
之后甲和乙模仿着管理员的思路,将自己的任务分成了类似的两个部分(挂“花边”还是不挂“花边”),分给了各自的两名手下去做。
最后会有人接到的任务是:
-
不考虑任何资源,网站能达到的猎奇度(必为零)加上之前已经挂上的资源的猎奇度是多少?
-
挂上“动漫”资源,不考虑任何资源,网站剩余的危险程度能容纳的最高猎奇度(必定为0)加上之前已经挂上的资源的猎奇度一共是多少?
这些人能够直接回答一个数字,而不用再将任务分给两个手下去做了。
每一个管理者将手下报告的数字中取一个最大值报给上级,最终甲和乙将数字报告给网站管理员,管理员选择最大的数值即是网站能达到的最大猎奇度。
为了知道最大猎奇度对应的挂了哪些资源,网站管理员只需判断甲和乙谁给的数字更大,如果甲更大说明没有挂“政治”,如果乙更大说明挂了。如果甲报的数字更大,则让甲看看两名手下谁报的数字更大,下面同理。如此可以得到该挂哪些资源。
看完上面的思路,可能第一反应是用递归的方法实现代码,递归实现的代码我直接放到第三部分,下面想说说如何用迭代实现这个计算过程。
迭代求解背包问题可以通过填一个表来实现,见表1。
剩余危险程度点数 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
不考虑任何资源 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
只考虑“动漫” | 0 |