算法提高 01背包

 

算法提高 01背包  

时间限制:1.0s   内存限制:256.0MB

    

问题描述

  给定N个物品,每个物品有一个重量W和一个价值V.你有一个能装M重量的背包.问怎么装使得所装价值最大.每个物品只有一个.

输入格式

  输入的第一行包含两个整数n, m,分别表示物品的个数和背包能装重量。
  以后N行每行两个数Wi和Vi,表示物品的重量和价值

输出格式

  输出1行,包含一个整数,表示最大价值。

样例输入

3 5
2 3
3 5
4 7

样例输出

8

数据规模和约定

  1<=N<=200,M<=5000.

 

#include<iostream>
#include<algorithm>
using namespace std;
int w[210],v[210];
int dp[210][5010];
int ans=0;
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>w[i]>>v[i];
	
	for(int i=1;i<=n;i++)
	for(int j=0;j<=m;j++)
	{
		if(j>=w[i])dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
		else dp[i][j]=dp[i-1][j];
		
	}
	cout<<dp[n][m]<<endl;
}

空间复杂度还可以进一步优化

#include<iostream>
#include<algorithm>
using namespace std;
int w[210],v[210];
int dp[5010];
int ans=0;
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>w[i]>>v[i];
	
	for(int i=1;i<=n;i++)
	for(int j=m;j>=w[i];j--)
	{
		dp[j]=max(dp[j-w[i]]+v[i],dp[j]);
	}
	cout<<dp[m]<<endl;
}

优化01背包的空间复杂度,对解决完全背包问题有一定的意义.

 

 

 

 

 

 

 

 

 

 

 

 

### 回答1: 01背包是一个经典的动态规划问题,用于求解在限制物品体积或重量的情况下,能够获得的最大价值。 算法流程: 1. 定义状态:f[i][j] 表示前i个物品,体积不超过j的最大价值。 2. 状态转移:f[i][j] = max(f[i-1][j], f[i-1][j-v[i]]+w[i]),其中v[i]表示物品i的体积,w[i]表示物品i的价值。 3. 边界:f[0][j] = 0,0 <= j <= V,V为背包体积。 代码实现: ``` def knapsack(v, w, V): n = len(v) f = [[0 for j in range(V+1)] for i in range(n+1)] for i in range(1, n+1): for j in range(1, V+1): if j < v[i-1]: f[i][j] = f[i-1][j] else: f[i][j] = max(f[i-1][j], f[i-1][j-v[i-1]]+w[i-1]) return f[n][V] ``` 总结:01背包是一个典型的动态规划问题,通过定义状态,计算状态转移方程,以及初始化边界,即可解决该问题。 ### 回答2: 01背包问题是一个经典的动态规划问题,也是算法和编程中常见的考察点之一。给定一组物品,每个物品都有自己的重量和价值,在限定的背包容量下,选择一些物品放入背包中,使得背包中物品的总价值最大化。 解决01背包问题的常用方法是使用动态规划。我们可以定义一个二维数组dp,其中dp[i][j]表示在前i个物品中,背包容量为j的情况下,能够达到的最大价值。 基本思路是,对于每个物品i,我们可以有两种选择:放入背包或者不放入背包。如果我们选择将物品i放入背包中,那么背包的容量将减少weight[i],同时总价值将增加value[i];如果我们选择不放入物品i,那么背包的容量和总价值都不会发生变化。因此,我们可以通过比较这两种选择的结果,取较大的那个来更新dp[i][j]。 具体的动态规划转移方程如下: 1. 如果物品i的重量大于背包容量j,即weight[i] > j,那么dp[i][j] = dp[i-1][j],即不放入物品i,结果和前i-1个物品相同。 2. 如果物品i的重量小于等于背包容量j,即weight[i] <= j,有两种选择: a. 放入物品i:dp[i][j] = dp[i-1][j-weight[i]] + value[i] b. 不放入物品i:dp[i][j] = dp[i-1][j],结果和前i-1个物品相同。 3. 最终的结果为dp[n][c],即在前n个物品中,背包容量为c的情况下,所能达到的最大价值,其中n为物品的总个数,c为背包的容量。 通过动态规划的思想,我们可以逐步计算出dp数组的所有值,并找出最终的结果。该方法的时间复杂度为O(n*c),空间复杂度为O(n*c)。 在实际应用中,我们可以根据题目的具体要求进相应的优化,如利用一维数组进降维优化、使用滚动数组减少空间复杂度等。不同的优化方法可以根据具体情况灵活运用,以提高算法的效率。 ### 回答3: 01背包问题是一种经典的动态规划问题,它是指在一组不同重量和不同价值的物品中,选择一部分物品装入背包,使得背包中物品的总价值最大,同时不能超过背包的重量限制。 解决01背包问题的关键是构建一个二维数组dp,其中dp[i][j]表示在前i个物品中,背包容量为j时的最大价值。根据动态转移方程dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]]+v[i]),可以逐步更新dp数组,最终得到dp[n][W]的最大价值。 具体的实现中,我们可以使用两层循环来更新dp数组。外层循环遍历物品,内层循环遍历背包容量,通过比较选择是否将当前物品放入背包。当物品的重量小于等于背包容量时,我们可以选择放入背包,此时背包中的总价值为dp[i-1][j-w[i]]+v[i];如果不放入背包,背包中的总价值为dp[i-1][j],取两者的较大值更新dp[i][j]。如果物品的重量大于背包容量,则不可能放入背包,即dp[i][j]保持不变。 最后,dp[n][W]即为所求的最大价值。可以通过反向遍历dp数组,根据dp[i][j]和dp[i-1][j]是否相等,判断物品i是否放入了背包,从而确定所选择的物品。 总之,通过动态规划的思想,我们可以解决01背包问题。这个问题有着广泛的应用,在资源分配、装箱、旅路线规划等领域都有着重要的作用。 希望以上回答对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值