思路
其实只要把内部循环顺序反过来就可以了,01背包问题是从大到小的顺序的原因就是使得前面的数据不被更新,也就是f[i-v[i]]的数据是上一次i-1的时候的数据,所以这样算出来,是只有一个i物品的,如果反过来,那就意味着递推公式中用了已经计算过的值,那么i物品就被使用若干个了。
代码
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N=1005;
int f[N];
int v[N];
int w[N];
int main(){
int n;
int s;
cin >> n >> s;
for(int i=1;i<=n;i++){
scanf("%d%d",&v[i],&w[i]);
}
for(int i=1;i<=n;i++){
for(int j=v[i];j<=s;j++){
f[j]=max(f[j-v[i]]+w[i],f[j]);
}
}
cout << f[s];
}