多重背包的代码中为什么j和k层的循环不能调换
作者:
Maveric
,
2024-03-13 13:04:50
,
所有人可见
,
阅读 23
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 6050;
int f[N];
int n, m;
int main()
{
cin>>n>>m;
for(int i = 0; i < n; i ++)
{
int v, w, s;
cin>>v>>w>>s;
for(int j = m; j >= v; j --)
/*
为什么k和j不能交换位置,这是因为如果先循环k的话,在迭代更新时
会受到前面数据的影响,导致所得出来的结果偏大。
举个例子 n = 2, m = 10 第一组2,1,5 (v,w,s)
k=1,更新f,此时f[10~2] = 1;
k=2,更新f,此时f[10] = f[v-k*v] + k*w = 3
!!!很明显,当k=2时f[10]应该等于2
这就是为什么k和j层顺序不能调换的原因
*/
//因此正确的写法是从大到小固定体积,然后遍历1~k,这样才能保证f的迭代更新不会受到f[j]前面数据的影响
for(int k = 1; k * v <= j && k <= s; k++)
f[j] = max(f[j], f[j - k*v] + k * w);
}
cout<<f[m];
}