0-1背包
- 问题描述:有一个容量为 V 的背包,和一些物品。这些物品分别有两个属性,体积 w 和价值 v,每种物品只有一个。要求用这个背包装下价值尽可能多的物品,求该最大价值,背包可以不被装满。
- 问题分析:对于0-1背包问题的最优解,每个物品只有两种情况,要么装入要么不装入(分别对应1和0),因此采用递归思想可以得出其状态转移方程。
在下面分析中用dp[i][j]数组表示容量为j的背包装i种物品时的最大价值;
找子问题:对于第i个物品要考虑的有两种情况;第一,包的容量可以装不下物品,这时背包所装物品的最大价值dp[i][j]和dp[i-1][j]相等;第二种情况是包的剩余容量大于第i个物品的重量,这时可以选择装入或者不装入第i个物品,我们对于装入方式的选择也是基于哪种情况下会使得背包所含物品的价值最大而决定。这时背包可装物品的最大价值就是dp[i-1][j-weight(i)]+value[i]和dp[i-1][j]中的大者。
确定状态转移方程:由上面的分析可以得出
** 当j<weight[i]时:dp[i][j]=dp[i-1][j]
当j>=eight[i]时:dp[i][j]=max(dp[i-1][j-weight(i)]+value[i],dp[i-1][j])**
解决0-1背包问题的C++代码实现如下
#include<iostream>
using namespace std;
const int MAX=1000+10;
int weight[MAX];
int value[MAX];
//dp[i][j]表示背包容量为j时对于i件物品的最大价值
int dp[MAX][MAX];
int main(){
//m代表背包容量,n代表物品数量
int m,n;
while(cin>>m>>n){
for(int i=1;i<=n;i++)
cin>>weight[i]>>value[i];
//第0行和列的dp值默认为零,分别对应0种物品和背包容量为0的情况
for(int i=0;i<=n;i++)
dp[i][0]=0;
for(int j=0;j<=m;j++)
dp[0][j]=0;