思路:
完全背包
储备:
问题重点:
1、二维:01和完全都可以交换遍历顺序
01背包理论基础(二维数组) (opens new window)中我们讲过,01背包二维DP数组,先遍历物品还是先遍历背包都是可以的。
因为两种遍历顺序,对于二维dp数组来说,递推公式所需要的值,二维dp数组里对应的位置都有。
大家可以看出,虽然两个for循环遍历的次序不同,但是dp[i][j]所需要的数据就是左上角,根本不影响dp[i][j]公式的推导!
一维:01不可以。完全背包可以。
主要就是看要用到的值在表格里是否已经遍历过了可以用了
01:
再来看看两个嵌套for循环的顺序,代码中是先遍历物品嵌套遍历背包容量,那可不可以先遍历背包容量嵌套遍历物品呢?
不可以!
因为一维dp的写法,背包容量一定是要倒序遍历(原因上面已经讲了),如果遍历背包容量放在上一层,那么每个dp[j]就只会放入一个物品,即:背包里只放入了一个物品。
完全:
在完全背包中,对于一维dp数组来说,其实两个for循环嵌套顺序是无所谓的!
最后:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,m;
cin>>n>>m;
vector<int> w(n,0),v(n,0);
for (int i=0;i<n;i++) cin>>w[i]>>v[i];
vector<int> dp(m+1);
for (int i=0;i<n;i++) {//把一个个物品放入背包
for (int j=w[i];j<=m;j++) {//腾出空间看放不放的下
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
cout<<dp[m];
return 0;
}