接着上一篇的话题
PS:上一篇链接
T1:多重背包
多重背包,就是每种物品可以拿最多k个
例题1:庆功会
登录 - 沐枫OJhttps://www.mfstem.org/p/567 这题的范围很小,我们可以用01背包完成
可以转化为01背包
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,a[5050],b[5050],t,f[6666];
signed main(){
cin >> n >> m;
for(int i = 1,q,p,r;i <= n;++i){
cin >> q >> p >> r;
for(int j = 1;j <= r;++j){
++t;
a[t] = q,b[t] = p;
}
}
for(int i = 1;i <= t;++i){
for(int j = m;j >= a[i];--j){
f[j] = max(f[j],f[j - a[i]] + b[i]);
}
}
cout << f[m] << endl;
return 0;
}/*5 1000
80 20 4
40 50 9
30 50 7
40 30 6
20 20 1
*/
练习:逃亡的准备
登录 - 沐枫OJhttps://www.mfstem.org/p/559
T2:分组背包
登录 - 沐枫OJhttps://www.mfstem.org/p/570分组背包,就是,将m个物品分成k组
其实就是枚举每组中选谁
#include<bits/stdc++.h>
using namespace std;
int v,n,t;
int w[35],c[35];
int a[15][35],f[205];
int main(){
cin >> v >> n >> t;
for(int i = 1,p;i <= n;++i){
cin >> w[i] >> c[i] >> p;
a[p][++a[p][0]] = i;
}
for(int i = 1;i <= t;++i){
for(int j = v;j >= 1;--j){
for(int k = 1;k <= a[i][0];++k){
if(j >= w[a[i][k]]){
int q = a[i][k];
//更新
if(f[j] < f[j - w[q]] + c[q])f[j] = f[j - w[q]] + c[q];
}
}
}
}
cout << f[v] << endl;
return 0;
}