当前位置: 首页 > news >正文

背包问题(1)

大一学了 大三复习一下巩固一下知识;

装箱问题_牛客题霸_牛客网https://www.nowcoder.com/practice/55100a6608ad4656849dbd1f16d044cb?tpId=308&tqId=170605&sourceUrl=%2Fexam%2Foj%3FquestionJobId%3D10%26subTabName%3Donline_coding_page

实例

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextInt()) { // 注意 while 处理多个 caseint a = in.nextInt();int b = in.nextInt();System.out.println(a + b);}}
}

第一次试错(贪心):

import java.util.Scanner;//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {public static void main(String[] args) {//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text// to see how IntelliJ IDEA suggests fixing it.Scanner scanner = new Scanner(System.in);//箱子容量int boxv= scanner.nextInt();//物品数量int object_num = scanner.nextInt();int[] object = new int[object_num];for(int i = 0; i < object_num; i++){object[i] = scanner.nextInt();}int res = boxv;for(int i = 0; i < object_num; i++){if (boxv-object[i] > 0) {boxv = Math.min(boxv - object[i], boxv);}}System.out.println(boxv);}}

错误之处 贪心思想只能解决局部最优 无法结局全局最优

解题思路

动态规划

import java.util.Scanner;//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
public class Main {public static void main(String[] args) {//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text// to see how IntelliJ IDEA suggests fixing it.Scanner scanner = new Scanner(System.in);//箱子容量int boxv= scanner.nextInt();//物品数量int object_num = scanner.nextInt();int[] object = new int[object_num+1];for(int i = 0; i < object_num; i++){object[i] = scanner.nextInt();}int[] dp = new int[boxv+1];//盒子中的体积for(int i = 0; i < object_num; i++){//每个物品只使用一次 倒序遍历for (int j = boxv; j >= object[i]; j--){dp [j] = Math.max(dp[j],dp[j-object[i]]+object[i]);}}System.out.println(boxv-dp[boxv]);}}
  • 状态定义
    dp[j] 表示容量为 j 时能装入的最大总体积
    这个定义直接对应问题目标:我们需要的最终结果就是 dp[V](容量为 V 时的最大装入体积)。

回溯剪枝

import java.util.Scanner;public class Main {static int[][] f; // 记忆化数组public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int V = scanner.nextInt(); // 箱子容量int n = scanner.nextInt(); // 物品数量int[] v = new int[n];      // 物品体积数组// 读取每个物品的体积for (int i = 0; i < n; i++) {v[i] = scanner.nextInt();}// 初始化记忆化数组,-1表示未计算f = new int[n + 1][V + 1];for (int i = 0; i <= n; i++) {for (int j = 0; j <= V; j++) {f[i][j] = -1;}}// 计算最大能装入的体积int maxVolume = dp(v, V, n);// 输出剩余空间System.out.println(V - maxVolume);}// 递归函数:计算前n个物品,容量为V时的最大装入体积static int dp(int[] v, int V, int n) {// 如果已经计算过,直接返回结果if (f[n][V] >= 0) {return f[n][V];}// 边界条件:没有物品时,最大体积为0if (n == 0) {return 0;}// 当前物品体积小于等于容量,可以选或不选if (V >= v[n - 1]) {f[n][V] = Math.max(dp(v, V, n - 1),dp(v, V - v[n - 1], n - 1) + v[n - 1]);} else {// 当前物品体积大于容量,不能选f[n][V] = dp(v, V, n - 1);}return f[n][V];}
}    
  • 状态转移逻辑
    对于每个物品体积 w,有两种选择:

    • 不选:则容量为 j 时的最大体积仍为 dp[j]
    • :前提是 j≥w,此时需要用前 i−1 个物品填满 j−w 的容量,再加上当前物品的体积 w,即 dp[j-w] + w
      因此,状态转移方程为:dp[j]=max(dp[j], dp[j−w]+w)
      逆序遍历容量(从 V 到 w)是为了确保每个物品只被选一次(避免重复计算),这是 01 背包的核心优化技巧。
  1. 回溯法(带剪枝):通过递归枚举所有可能的物品组合,并在当前体积超过容量时提前终止(剪枝)。对物品体积从大到小排序可以更快触发剪枝条件。
  2. 记忆化搜索:递归实现动态规划,通过记忆化数组避免重复计算,代码结构更直观。

http://www.xdnf.cn/news/591805.html

相关文章:

  • Java RestTemplate 通用请求工具类
  • 2024游戏安全白皮书:对抗激烈!PC游戏外挂功能数增长超149%,超85%移动外挂为定制挂(附获取方式)
  • 基于阿里云DashScope API构建智能对话指南
  • 写一个计划任务脚本(定时执行)
  • PostgreSQL跨数据库表字段值复制实战经验分
  • 对于从事FPGA行业的人来说,需要掌握哪些知识
  • ant design 日历组件a-calendar如何汉化
  • 二分算法的补充说明
  • 表格单元格多行文本溢出写法
  • 基于SpringBoot的美食分享平台设计与开发(Vue MySQL)
  • 高效数据库管理新体验:SQLynx 3.7 功能解析与团队协作场景实践
  • 06算法学习_58. 区间和
  • PrimeVue菜单组件深度解析:构建高效能的Web导航系统
  • 3 tomcat原理
  • 多元回归的假设检验
  • Linux中 I/O 多路复用机制的边缘触发与水平触发
  • 鸿蒙运动开发:计算户外运动步频与步幅,与地图路线绘制
  • 链表-环形链表||
  • 3.8.2 利用RDD计算总分与平均分
  • Java 多线程编程:解锁高性能应用开发的密钥
  • RAG系统实战:文档切割与转换核心技术解析
  • Golang 访问 map 中的结构体字段时如何避免拷贝
  • 无anaconda搭建yolo11环境
  • 鸿蒙进阶——CMakelist、GN语法简介及三方库通用移植指南
  • 技术篇-2.3.Golang应用场景及开发工具安装
  • 晶振选型三大陷阱:工作温度、电压与负载电容的隐藏矛盾
  • 【AT32】 at32 软复位
  • mssql查询历史执行过的语句日志
  • 提示词工程驱动Mermaid图表生成:技术原理与实战案例
  • 力扣面试150题-- 二叉树展开为链表