01背包问题

本文介绍了使用动态规划方法解决背包问题的过程,通过递推式计算在给定背包容量和物品数量下,如何选择物品以最大化总价值。代码展示了如何初始化数组和计算dp[i][j]的值,关键在于考虑物品是否放入背包及带来的价值增益。
摘要由CSDN通过智能技术生成

      题目描述: 

 按图中样例分析

已知输入:

物品编号

1

2

3

4

重量weight

1

2

3

4

价值value

2

4

4

5

 物品个数为:4、背包总容量为:5。建立数组v[i]储存价值,w[i]储存重量。

 建立二维数组dp[i][j],横轴为j,代表背包容量大小,纵轴为i代表第i个物品。

0

1

2

3

4

5

6

7

8

0

0

0

0

0

0

0

0

0

0

1

0

2

2

2

2

2

2

2

2

2

0

2

4

6

6

6

6

6

6

3

0

2

4

6

6

8

10

10

10

4

0

2

4

6

6

8

10

11

11

解决此问题的关键是找出递推式 

表中二维数组dp[i][j]的值代表的是放入容量为j的前i件物品的最大价值。如当i=1,j>1时,第一件物品的体积为1价值为2,此时的背包均可放下,所以价值都为2.

物体的状态共有两种:放与不放。

不放:

当j<w[i]时,说明就算此刻背包是空的,也放不进第i件物品,所有此刻背包的最大价值就是之前的最大价值:dp[i-1][j]。因为它根本就放不进去第i见物品,所以不用考虑。

放:

当j>=w[i]时,此时可以放进背包。但要判断放了价值更高还是不放价值高。判断的方法就是先找到dp[i-1][j-w[i]],i-1说明是还没放,j-w[i]就是背包容量减去此物品还剩下的容量。也就是找到没放这个物品之前它的最大价值。然后dp[i-1][j-w[i]]+v[i]就是放了这个物品的最大价值,让它再与dp[i-1][j]比较大小,取大者赋给此时的dp[i][j]。

具体代码如下:

#include <bits/stdc++.h>
using namespace std;
int bag(int n,int m); 
int num[1001][1001]={0};
int v[1001];
int w[1001];
int main()
{
	int N,V,i;
	cin>>N>>V;
	for(i=1;i<=N;i++){
		cin>>w[i]>>v[i];
	}
	cout<<bag(N,V);
}
int bag(int n,int m)
{
	int i,j;
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			if(j<w[i]){
				num[i][j]=num[i-1][j];
			}
			else{
				num[i][j]=max(num[i-1][j],num[i-1][j-w[i]]+v[i]);	
			}
		}
	}
	return num[n][m];
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值