1、视频链接:E10 背包DP 多重背包 二进制优化_哔哩哔哩_bilibili
#include <bits/stdc++.h>
using namespace std;
const int N=210;
int n,m;
int v[N],w[N],s[N];//s是数量
int f[N];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&v[i],&w[i],&s[i]);
}
for(int i=1;i<=n;i++){
for(int j=m;j>=v[i];j--){
for(int k=0;k<s[i]&&k*v[i]<=j;k++){
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
}
}
}
printf("%d\n",f[m]);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N=2005;
int n,m;
int v1,w1,s;
int v[N*12],w[N*12];
int f[N];
int main(){
cin>>n>>m;
//二进制拆分
int num=0;
for(int i=1;i<=n;i++){
cin>>v1>>w1>>s;
for(int j=1;j<=s;j<<=1){
v[++num]=j*v1;
w[num]=j*w1;
s-=j;
}
if(s){//剩余的
v[++num]=s*v1;
w[num]=s*w1;
}
}
//转化成了01背包
for(int i=1;i<num;i++){//因为num++了,所以到num-1即可
for(int j=m;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[m];
return 0;
}
题目链接:宝物筛选 - 洛谷
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
int n,m,a,b,s;
int v[N],w[N];
int f[N];
int main(){
cin>>n>>m;
int cnt=0;
for(int i=1;i<=n;i++){
cin>>b>>a>>s;
for(int j=1;j<=s;j<<=1){
v[++cnt]=j*a;
w[cnt]=j*b;
s-=j;
}
if(s){
v[++cnt]=s*a,w[cnt]=s*b;
}
}
for(int i=1;i<=cnt;i++){
for(int j=m;j>=v[i];j--){
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
}
cout<<f[m];
return 0;
}