背包问题递归算法java编程_背包问题 -- 1) 思路,递归求解

本文介绍了背包问题的递归算法思想,通过一个包含物品大小和价值的实例展示了如何计算背包在给定容积下的最大价值。虽然递归算法直观,但由于存在大量重复计算,效率较低。下篇将探讨如何使用动态编程进行改进,以提高效率。
摘要由CSDN通过智能技术生成

最近看了《算法I-IV(C++语言描述)》中关于动态编程求解背包问题的部分,感觉书中描述的不是很详细,在这里通过我个人的理解再加上书中的描述,再重温下这一经典问题的动态编程求解方法。

所谓的背包问题,可以描述如下:一个小偷打劫一个保险箱,发现柜子里有N类不同大小与价值的物品,但小偷只有一个容积为M的背包来装东西,背包问题就是要找出一个小偷选择所偷物品的组合,以使偷走的物品总价值最大。我们可以定义以下结构:

struct Item {

int size;            //保存物品大小

int val;             //保存物品价值

};

例如有下表中的物品:

Index

0

1

2

3

4

Item

A

B

C

D

E

Size

3

4

7

8

9

Val

4

5

10

11

13

上表中第一行(Index)是物品在程序中的索引号,第二行(Item)是物品的标示,第三行(Size)是物品的大小,第四行(Val)是物品的价值,而每一列又对应了一类物品。假设小偷背包的容积为17,则小偷能够拿走5个A价值为20的物品,或者1个D和1个E,价值为24的物品,等等。

为了使小偷在背包容积为cap的情况下,能够偷走最大价值的物品,我们可以假设小偷足够聪明,无论背包容积cap为多少,小偷总能找到最优的组合使背包中所装物品的价值最大。

倘若我们定义函数:

int  knap( int cap );

该函数的返回值为容积为cap的背包所装物品的最大价值。对于cap为17的背包,因为有5类物品,所以所装物品的价值有以下组合:

1) 4 + knap( 17 - 3 ),即 item[0].val + knap(cap - item[0].size);

2)     5 + knap( 17 - 4 ),即 item[1].val + knap(cap - item[1].size);

3)    10 + knap( 17 - 7 ),即 item[2].val + knap(cap - item[2].size);

4)     11 + knap( 17 - 8 ),即 item[3].val + knap(cap - item[3].size);

5)     13 + knap( 17 - 9 ),即 item[4].val + knap(cap - item[4].size);

因为小偷已经帮助我们找到了cap = cap - item[i].size的最优组合,所以我们只需要找到item[i].val + knap(cap - item[i].size)的最大值也就完称了我们的任务了。

下面的程序代码是按以上的思路编写的:

1134918024.jpg

我么定义了一个类型为Item的N项数组,对于每一个可能的项,我们递归的计算所能得到的最大值,然后挑出那些值中的最大项返回。

需要说明的是,上面的代码不应该成为正式的代码,如果按上面的代码画出每次函数调用的二叉树图,就会发现有大量重复的计算来处理同一个问题,其结果就是耗费指数级的时间,因而是低效的。

下一篇《背包问题 -- 2) 改进,自顶向下的动态编程》将会介绍如何对上面的代码改进,使耗费的时间从指数级减少到线性级。

posted on 2006-01-03 23:15 PIGWORLD 阅读(7994) 评论(5)  编辑 收藏 引用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值