01背包详解(二维到一维)

 

有 N件物品和一个容量为 V 的背包,每件物品有各自的价值且只能被选择一次,要求在有限的背包容量下,装入的物品总价值最大。「0-1 背包」是较为简单的动态规划问题,也是其余背包问题的基础。

动态规划是不断决策求最优解的过程,「0-1 背包」即是不断对第 i个物品的做出决策,「0-1」正好代表不选与选两种决定。

二维代码实现

#include<iostream>
using namespace std;
const int N=1e3+10;
int v[N],w[N],f[N][N];

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
	
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m;j++){
			f[i][j]=f[i-1][j];  //当前背包容量j<v[i],所以前i个物品最大值与前i-1个相同  
			if(j>=v[i])   //如果j>v[i],进行选择放与不放第i个物品
			f[i][j]=max(f[i][j],f[i-1][j-v[i]]+w[i]);
		}
	}
	cout<<f[n][m]<<endl;
	return 0;
}

一维代码 

#include<iostream>
using namespace std;
const int N=1e3+10;
int v[N],w[N],f[N];

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>v[i]>>w[i];
	
	
	for(int i=1;i<=n;i++){
		for(int j=m;j>=a[i];j--){
			f[j]=max(f[j],f[j-v[i]]+w[i]);  //背包容量是从大到小的因此j一定大于a[i] 
		}
	}
	cout<<f[m]<<endl;
	return 0;
}
for(int j=m;j>=a[i];j--){
			f[j]=max(f[j],f[j-v[i]]+w[i]);  //背包容量是从大到小的因此j一定大于a[i] 
		}

一定要从m开始进行逆序计算,在二维情况下f[i][j]是由i-1的状态得来的,f[i][j]与f[i-1][j]是完全独立的,但是当我们优化到一维后我们可能会在该使用i-1的位置用到i,例如,一维状态第i轮对体积为 3的物品进行决策,则f[7]f[4]更新而来,这里的f[4]正确应该是f[i - 1][4],但从小到大枚举j这里的f[4]在第i轮计算却变成了f[i][4]。当逆序枚举背包容量j时,我们求f[7]同样由f[4]更新,但由于是逆序,这里的f[4]还没有在第i轮计算,所以此时实际计算的f[4]仍然是f[i - 1][4]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值