声明各个变量的含义,便于理解代码
bag:表示背包的空间
n:表示商品的数量
w[3]={0,3,1}存放每个商品占据空间 ,空出第一个位置,使得下标从1开始
v[3]={0,2,5}存放每个商品占有价值 ,空出第一个位置,使得下标从1开始
dp[bag]数组表示当前背包的容量,代码初始空间为0
#include<iostream>v
#include<cstring>
using namespace std;
int w[3]={0,3,1};
int v[3]={0,2,5};
int dp[1005];
int main()
{
int bag,n;
cin>>bag>>n;
for( int i=1;i<=n;i++)
{
for(int j=bag;j>=w[i];j--)
{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
cout<<dp[bag]<<endl;
return 0;
}
核心代码分析
for( int i=1;i<=n;i++) //有几个商品遍历几次
{
for(int j=bag;j>=w[i];j--)
//每次遍历从原始背包空间开始,只要背包能装下第 i 个物品,就把它放进来
{
//去比较现在背包的价值dp[j]与装完第 i 个商品后的价值dp[j-w[i]]+v[i]
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
int w[3]={0,3,1};
int v[3]={0,2,5};
i=1 j=bag(4) ------dp[4]=2
i=1 j=bag(3)-------dp[3]=2
i=1 j=bag(2)-------dp[2]=0 当背包空间为3的时候刚好装一下第一个商品。
经过第一次遍历dp[]={0,0,2,2};
++++++++++++++++++++++++++++++++++++++++++++++++++++++
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
i=2 j=bag(4)-------max(dp[4]=2,dp[4-1]+v[2])======dp[4]=2+5
i=2 j=bag(3)-------max(dp[3]=2,dp[3-1]+v[2])======dp[3]=0+5
i=2 j=bag(2)-------max(dp[2]=0,dp[2-1]+v[2])======dp[2]=0+5
i=2 j=bag(1)-------max(dp[1]=0,dp[1-1]+v[2])======dp[1]=0+5
++++++++++++++++++++++++++++++++++++++++++++++++++++++
经过两次遍历,dp[4]里面存放的价值最大。
为什么时dp[4]?
因为每次遍历的时候 j 变量都是从原始背包空间开始的,经过递归之后,最大结果就是dp[bag]