多重背包与01背包模型和完全背包模型的区别
他们的主要区别主要在于,01背包只给你1个物品,完全背包模型给你无限个物体,多重背包模型是个你有限个物体
朴素做法
因为数量多了,所以就相当于01循环再套一个循环,这个循环用来循环这个有限个数量的,
for(int i = 1 ; i <= n ; i++){
for(int j = 0 ; j <= m ; j++){
for(int k = 0 ; k <= s[i] && k * v[i] <= j ; k++){
f[i][j] = max(f[i][j] , f[i - 1][j - v[i] * k] + k * w[i]);
}
}
}
一维优化版本(也是通过从大到小,来使用未更新的i-1时的权值)
for(int i = 1 ; i <= n ; i++){
for(int j = m ; j >= 0 ; 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]);
}
}
}
快速幂优化(二进制)
快速幂的本质就是把一个数的指数二进制化,拆分成指数为二的次幂相乘的形式
技巧:我们把每个物品倍乘,当作单独的一个物品,然后处理它就变成了一个01背包问题,优化掉他的个数问题,把多个物体看成一个物体
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 250000 , M = 2500;
int n , m ;
int v[N] , w[N] , f[N];
int main(){
cin>>n >> m;
int cnt = 0;
for(int i = 1 ; i <= n ; i++){
int a, b, s;
cin>>a>>b>>s;
int k = 1;
while(k <= s){
cnt ++;
v[cnt] = a * k;
w[cnt] = b * k;
s -= k;
k *= 2;
}
if(s > 0){
cnt ++;
v[cnt] = a * s;
w[cnt] = b * s;
}
}
n = cnt;
for(int i = 1 ; i <= n ; i ++){
for(int j = m ; j >= v[i] ; j --){
f[j] = max(f[j] , f[j - v[i]] + w[i]);
}
}
cout<<f[m]<<endl;
return 0;
}