用滚动数组求解0/1背包问题

用滚动数组求解0/1背包问题(此处仅求装入背包的最大价值)

//
由于第i个阶段(考虑物品i)的解dp[i][ * ]只与第i-1个阶段(考虑物品i-1)的解dp[i-1][ * ]有关,这种情况下保存更前面的数据已经毫无意义。

因此可以利用滚动数组进行优化,将dp数组由dp[MAXN][MAXN]改为dp[2][MAXN]。

因此0/1背包问题的状态转移方程如下:

dp[0][0]=0,dp[1][0]=0
dp[0][r]=0
dp[c][r]=dp[1-c][r] (当r<w[i]时,物品i放不下)
dp[c][r]=MAX{dp[1-c][r],dp[1-c][r-w[i]]+v[i]}
(否则在不放入和放入物品i之间选择最优解)

代码实现:

#include<stdio.h>
#define MAXN 20					
#define MAXW 100
 int n=5,W=10;
 int w[MAXN]={0,2,2,6,5,4};
 int v[MAXN]={0,6,3,5,4,6};
 int dp[1][MAXW];
 int max(int a,int b){
 	return a>b?a:b;
 }
 void Knap(){
 	int i,r;
 	int c=0;
 	for(int i=0;i<=1;i++)
 	dp[i][0]=0;
 	for(int r=0;r<=W;r++)
 	dp[0][r]=0;
 	for(int i=1;i<=n;i++){
 		c=1-c;
 		for(int r=1;r<=W;r++){
 			if(r<w[i])  dp[c][r]=dp[1-c][r];
 			else
 			dp[c][r]=max(dp[1-c][r],dp[1-c][r-w[i]]+v[i]);
		 }
	 }
 }
 int main(){
 	Knap();
	printf("总价值=%d\n",max(dp[0][W],dp[1][W]));
 	return 0;
 }
 

参考自《算法设计与分析》第二版 李春葆

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值