有 N 种物品和一个容量是 V的背包。
第 ii 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N,V,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,,si,用空格隔开,分别表示第 ii 种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N≤10000<N≤1000
0<V≤20000<V≤2000
0<vi,wi,si≤20000<vi,wi,si≤2000
提示:
本题考查多重背包的二进制优化方法。
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
思想:之后就是选与不选。将其转化为01背包问题!

//不需要枚举那么多,将其分组,分组之后的合并和之前枚举的一样即可,相当于买一包不买一个
import java.io.*;
import java.lang.*;
class Main{
static int n = 0, m = 0, N = 20010;
static int[] f = new int[N];
static int[] v = new int[N], w = new int[N];
public static void main(String[] args)throws Exception{
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String[] params = buf.readLine().split(" ");
n = Integer.valueOf(params[0]);
m = Integer.valueOf(params[1]);
int cnt = 0;
for(int i = 1; i <= n; ++i){
int k = 1;
String[] info = buf.readLine().split(" ");
int a = Integer.valueOf(info[0]);
int b = Integer.valueOf(info[1]);
int s = Integer.valueOf(info[2]);
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] = Math.max(f[j], f[j - v[i]] + w[i]);
}
}
System.out.print(f[m]);
}
}
本文探讨了一种解决多重背包问题的有效方法,通过二进制优化技术将问题转化为01背包问题,从而简化了计算过程并提高了效率。文章详细介绍了如何通过分组和合并策略来减少枚举次数,最终实现最大价值的求解。
413

被折叠的 条评论
为什么被折叠?



