【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题

简介: 本文介绍了经典的0/1背包问题及其动态规划解法。

 目录

背包问题简介

问题描述

输入:

输出:

动态规划解法

动态规划状态转移

代码实现

代码解释

动态规划的时间复杂度

例子解析

输出:

总结


作者我蓝桥杯:2023第十四届蓝桥杯国赛C/C++大学B组一等奖,所以请听我讲:

image.gif 编辑

蓝桥杯是一项备受推崇的编程比赛,参赛者需要通过高效的算法解决各种具有挑战性的问题。今天,我们将深入探讨蓝桥杯经典算法题目之一——0/1背包问题。通过这个题目,我们不仅可以学习如何高效使用动态规划,还能够更好地掌握如何在实际问题中应用算法思想。

背包问题简介

🍎背包问题的核心思想是:给定一组物品,每个物品有一个重量和一个价值,现在有一个背包,背包的容量有限,问如何选择物品放入背包,使得在不超过背包容量的情况下,物品的总价值最大。🍊

应该也很要理解,就是这么个道理:

🍏在0/1背包问题中,每个物品只能选择放入背包一次,要么放入背包,要么不放入。🍏

image.gif 编辑

image.gif 编辑

问题描述

那我们假设我们有一个背包,他的容量为C,有n个物品。其中每个物品有一个重量wi和一个价值vi。我们需要在这些物品中选择若干个物品放入背包,使得背包中物品的总价值最大,并且物品的总重量不超过背包的容量。就是这个问题。

输入:

  • 第1行:nC,表示物品的数量和背包的容量。
  • 第2至n+1行:每行包含两个整数wivi,分别表示第i个物品的重量和价值。

输出:

  • 输出一个整数,表示在不超过背包容量的前提下,能够获得的最大价值。

动态规划解法

是一种通过将复杂问题分解成子问题来求解的方法。在背包问题中,我们可以定义一个二维数组dp[i][j],表示前i个物品中能够在容量为j的背包中获得的最大价值。

image.gif 编辑

动态规划状态转移

  • 如果第i个物品不放入背包,那么dp[i][j] = dp[i-1][j],即最大价值与不放入这个物品时的最大价值相同。🥞🥞🥞🥞
  • 如果第i个物品放入背包,那么dp[i][j] = dp[i-1][j-wi] + vi,即最大价值为放入该物品后,剩余容量所能获得的最大价值。🍔🍔🍔🍔🍔

最终,我们要求解的是dp[n][C],即在n个物品和背包容量C下,能够获得的最大价值。

代码实现

import java.util.Scanner;
public class Knapsack {
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        // 输入物品数量和背包容量
        int n = sc.nextInt();
        int C = sc.nextInt();
        
        // 定义物品的重量和价值
        int[] weight = new int[n + 1];
        int[] value = new int[n + 1];
        
        // 输入每个物品的重量和价值
        for (int i = 1; i <= n; i++) {
            weight[i] = sc.nextInt();
            value[i] = sc.nextInt();
        }
        // dp数组,dp[i][j]表示前i个物品,背包容量为j时的最大价值
        int[][] dp = new int[n + 1][C + 1];
        
        // 动态规划求解
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= C; j++) {
                if (j >= weight[i]) {
                    // 如果当前物品可以放入背包,则选择放与不放的最大值
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
                } else {
                    // 当前物品不能放入背包时,最大价值与不放当前物品时相同
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        // 输出最大价值
        System.out.println(dp[n][C]);
        sc.close();
    }
}

image.gif

代码解释

  1. 输入处理:首先通过Scanner读取物品数量n和背包容量C,然后通过循环输入每个物品的重量和价值。
  2. DP数组:使用一个二维数组dp[i][j]表示在前i个物品和容量为j的背包中能获得的最大价值。
  3. 状态转移:遍历每个物品,对于每种可能的背包容量j,根据是否将当前物品放入背包,更新dp[i][j]
  4. 输出:最后输出dp[n][C],即在所有物品和背包容量下能够获得的最大价值。

都挺难的,大家好好消化吧,到时候更新更加详细的教程,方便大家理解。

动态规划的时间复杂度

该算法的时间复杂度是O(n * C),其中n是物品的数量,C是背包的容量。空间复杂度也是O(n * C),主要由dp数组占据。

例子解析

假设有如下输入:

4 5 2 3 3 4 4 5 5 6

这意味着有4个物品,背包容量为5,物品的重量和价值分别为:

物品 重量 价值
1 2 3
2 3 4
3 4 5
4 5 6

使用动态规划的算法,我们可以求得最大价值为7,即选择物品1(重量2,价值3)和物品2(重量3,价值4)放入背包中,背包容量为5,总价值为7。

输出:

7

image.gif 编辑

image.gif 编辑


相关文章
|
4月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
4月前
|
存储 缓存 监控
上网行为监控系统剖析:基于 Java LinkedHashMap 算法的时间序列追踪机制探究
数字化办公蓬勃发展的背景下,上网行为监控系统已成为企业维护信息安全、提升工作效能的关键手段。该系统需实时记录并深入分析员工的网络访问行为,如何高效存储和管理这些处于动态变化中的数据,便成为亟待解决的核心问题。Java 语言中的LinkedHashMap数据结构,凭借其独有的有序性特征以及可灵活配置的淘汰策略,为上网行为监控系统提供了一种兼顾性能与功能需求的数据管理方案。本文将对LinkedHashMap在上网行为监控系统中的应用原理、实现路径及其应用价值展开深入探究。
99 3
|
4月前
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
174 0
|
3月前
|
存储 算法 安全
Java中的对称加密算法的原理与实现
本文详细解析了Java中三种常用对称加密算法(AES、DES、3DES)的实现原理及应用。对称加密使用相同密钥进行加解密,适合数据安全传输与存储。AES作为现代标准,支持128/192/256位密钥,安全性高;DES采用56位密钥,现已不够安全;3DES通过三重加密增强安全性,但性能较低。文章提供了各算法的具体Java代码示例,便于快速上手实现加密解密操作,帮助用户根据需求选择合适的加密方案保护数据安全。
328 58
|
2月前
|
存储 负载均衡 算法
我们来说一说 Java 的一致性 Hash 算法
我是小假 期待与你的下一次相遇 ~
|
2月前
|
存储 监控 算法
企业上网监控场景下布隆过滤器的 Java 算法构建及其性能优化研究
布隆过滤器是一种高效的数据结构,广泛应用于企业上网监控系统中,用于快速判断员工访问的网址是否为违规站点。相比传统哈希表,它具有更低的内存占用和更快的查询速度,支持实时拦截、动态更新和资源压缩,有效提升系统性能并降低成本。
53 0
|
5月前
|
存储 机器学习/深度学习 监控
如何监控员工的电脑——基于滑动时间窗口的Java事件聚合算法实现探析​
在企业管理场景中,如何监控员工的电脑操作行为是一个涉及效率与合规性的重要课题。传统方法依赖日志采集或屏幕截图,但数据量庞大且实时性不足。本文提出一种基于滑动时间窗口的事件聚合算法,通过Java语言实现高效、低资源占用的监控逻辑,为如何监控员工的电脑提供一种轻量化解决方案。
122 3
|
7月前
|
存储 算法 Java
算法系列之动态规划
动态规划(Dynamic Programming,简称DP)是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题,并存储这些子问题的解来避免重复计算,从而提高算法的效率。
253 4
算法系列之动态规划
|
7月前
|
算法 安全 调度
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
|
7月前
|
机器学习/深度学习 算法 测试技术
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”
【动态规划篇】01 背包的逆袭:如何用算法装满你的 “财富背包”