01背包问题

01 背包问题

输入:

n个商品组成集合O,每个商品有两个属性vi和pi,分别表示体积和价格

背包容量为C

输出:

求解一个商品子集包含于O,令价格和最大,容量不超过C

直观上 : 价格高优先 , 体积小优先 , 性价比高优先 都不能得到最优解

解决方案一 : 蛮力枚举,递归求解(非DP)

递归函数:KnapsackSR(h,i,c) h: 首序号元素 i: 尾序号元素 c:剩余容量

knapsackSR(h,i,c) = max{ KnapsackSR(h,i-1,c-vi)+pi , knapsackSR(h,i-1,c) }

伪代码:

if c<0 then
	return -1
end
if i<=h-1 then
	return 0   商品规划完成
end
P1<--KnapsackSR(h,i-1,c-vi)
P2<--KnapsackSR(h,i-1,c)
P=max{P1+pi,P2}
return P

时间复杂度 : O(2^n)

解决方案二: 带备忘的递归方法(优化)

(DP,自顶向下)

KnapsackMR(h,i,c)

伪代码:

if c<0 then
	return -1
end
if i<=h-1 then
	return 0   商品规划完成
end

if P[i,c]!=NULL then
	return P[i,c]	当P[i,c]有值返回就行
end

P1<--KnapsackMR(h,i-1,c-vi)
P2<--KnapsackMR(h,i-1,c)
P[i,c]=max{P1+pi,P2}
return P[i,c]

解决方案三: 递推求解

(DP,自底向上)

KnapsackDR(h,i,c)

在这里插入图片描述

伪代码:

//初始化
创建二维数组P[n][c]和Rec[n][c]
//第一行第一列都是0
for i<- 0 to C do
	P[0,i]<-0
end
for i<- 0 to n do
	P[i,0]<-0
end

//求解表格
for i<- 1 to n do
	for c<- 1 to C do 
    	if(vi<=c)and(pi+P[i-1,c-vi]>P[i-1,c]) then
    		P[i,c]<- pi+P[i-1,c-vi]
    		Rec[i,c]<- 1
    	end
    	else
    		P[i,c]<- P[i-1,c]
    		Rec[i,c]<- 0
    	end
    end
end  

//输出最优方案
K<- C
for i<- n to 1 do
	if Rec[i,k] =1 then
		print 选择商品i
		K<- k-vi
	end
	else 
		print 不选商品i
	end
end
return P[n,c]

时间复杂度 : O(n C)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值