多重背包问题——二进制优化
前言
二进制优化,将每类物品的数量按2的整数次幂进行拆分,因为任何一个十进制数都可以用若干个二进制数来凑成
时间复杂度:O(NlogSV)
题目描述
有 N 种物品和一个容量是 V 的背包。
第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi。
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。
输出最大价值。
输入格式
第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。
接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。
输出格式
输出一个整数,表示最大价值。
数据范围
0<N≤1000
0<V≤2000
0<vi,wi,si≤2000
提示:
本题考查多重背包的二进制优化方法。
输入样例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
输出样例:
10
Java代码
1 import java.util.*; 2 3 public class Main { 4 5 static int N = 25000 + 10; 6 static int[] f = new int[N]; 7 static int[] v = new int[N]; 8 static int[] w = new int[N]; 9 10 public static void main(String[] args) { 11 Scanner in = new Scanner(System.in); 12 int n = in.nextInt(); 13 int m = in.nextInt(); 14 15 // 拆分后的物品种类 16 int cnt = 0; 17 while (n-- > 0) { 18 int a = in.nextInt(); 19 int b = in.nextInt(); 20 int s = in.nextInt(); 21 int k = 1; 22 while (k <= s) { 23 cnt++; 24 v[cnt] = a * k; 25 w[cnt] = b * k; 26 s -= k; 27 k *= 2; 28 } 29 if (s > 0) { 30 cnt++; 31 v[cnt] = a * s; 32 w[cnt] = b * s; 33 s -= s; 34 } 35 } 36 37 // 更新n 38 n = cnt; 39 40 // 01背包 41 for (int i = 1; i <= n; i++) { 42 for (int j = m; j >= v[i]; j--) { 43 f[j] = Math.max(f[j], f[j - v[i]] + w[i]); 44 } 45 } 46 47 System.out.println(f[m]); 48 } 49 50 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署
· 葡萄城 AI 搜索升级:DeepSeek 加持,客户体验更智能
2021-04-29 Maven工具的使用与配置、以及在IDEA中的配置
2021-04-29 牛客错题——计算机专业 Java C语言(持续更新)