【题目描述】
有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
【输入格式】
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。
【输出格式】
输出一个整数,表示最大价值。
【输入样例】
4 5
1 2 3
2 4 1
3 4 3
4 5 2
【输出样例】
10
【数据范围】
0<N≤1000
0<V≤2000
0<vi,wi,si≤200
提示:
本题考查多重背包的二进制优化方法。
核心
cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin>>n;
cout<<n<<"=";
int k=1;
while(k<=n) {
if(k==n) cout<<k;
else cout<<k<<"+";
n=n-k;
k=k*2;
}
if(n>0) cout<<n;
return 0;
}
/*
in1:26
out1:26=1+2+4+8+11
in2:7
out2:7=1+2+4
*/
代码如下
cpp
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e4+5;
int vol[maxn],val[maxn];
int f[maxn];
int n,v,cnt;
int main() {
cin>>n>>v;
for(int i=1; i<=n; i++) {
int volume,value,num;
cin>>volume>>value>>num;
int k=1;
while(k<=num) {
cnt++;
vol[cnt]=volume*k;
val[cnt]=value*k;
num=num-k;
k=k*2;
}
if(num>0) {
cnt++;
vol[cnt]=volume*num;
val[cnt]=value*num;
}
}
for(int i=1; i<=cnt; i++) {
for(int j=v; j>=vol[i]; j--) {
f[j]=max(f[j],f[j-vol[i]]+val[i]);
}
}
cout<<f[v]<<endl;
return 0;
}
/*
in:
4 5
1 2 3
2 4 1
3 4 3
4 5 2
out:
10
*/