【算法基础:动态规划】5.1 背包问题

news2024/9/24 15:24:13

文章目录

  • 01背包
    • 例题:2. 01背包问题
  • 完全背包
    • 例题:3. 完全背包问题
  • 多重背包
    • 例题:4. 多重背包问题 I
    • 例题:5. 多重背包问题 II(数据范围较大:二进制优化)
  • 分组背包
    • 例题:9. 分组背包问题

01背包

例题:2. 01背包问题

在这里插入图片描述

import java.util.*;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        int[] v = new int[n], w = new int[n];
        for (int i = 0; i < n; ++i) {
            v[i] = sc.nextInt();
            w[i] = sc.nextInt();
        }
        int[] dp = new int[m + 1];
        for (int i = 0; i < n; ++i) {           // 枚举物品
            for (int j = m; j >= v[i]; --j) {   // 枚举背包
                dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
            }
        }
        System.out.println(dp[m]);
    }
}

完全背包

例题:3. 完全背包问题

在这里插入图片描述

import java.util.*;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        int[] v = new int[n], w = new int[n];
        for (int i = 0; i < n; ++i) {
            v[i] = sc.nextInt();
            w[i] = sc.nextInt();
        }
        int[] dp = new int[m + 1];
        for (int i = 0; i < n; ++i) {           // 枚举物品
            for (int j = v[i]; j <= m; ++j) {   // 枚举背包
                dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
            }
        }
        System.out.println(dp[m]);
    }
}

多重背包

例题:4. 多重背包问题 I

在这里插入图片描述

把 多重背包拆分成 01背包即可。

import java.util.*;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        int[] v = new int[n], w = new int[n], s = new int[n];
        for (int i = 0; i < n; ++i) {
            v[i] = sc.nextInt();
            w[i] = sc.nextInt();
            s[i] = sc.nextInt();
        }
        int[] dp = new int[m + 1];
        for (int i = 0; i < n; ++i) {               // 枚举物品
            for (int k = 0; k < s[i]; ++ k) {       // 枚举 k 个物品
                for (int j = m; j >= v[i]; --j) {   // 枚举背包
                    dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
                }
            }
        }
        System.out.println(dp[m]);
    }
}

例题:5. 多重背包问题 II(数据范围较大:二进制优化)

在这里插入图片描述
这一题和上一题唯一不同的就是数据范围。

因此,本题考查的重点是:多重背包的二进制优化方法

核心思想是: 将每个物品的数量 x 分成若干组,每组的数量都是 2 的幂次。(因为分成这样若干个组之后,它们之间可以组合成 0 ~ s 的任意数量。)

在这里插入图片描述
将 1023 数量分组打包成 1,2,4,8,… 512。
这样就将一个循环的 O ( n ) O(n) O(n) 优化成了 O ( log ⁡ n ) O(\log{n}) O(logn)

那不能正好分成 2 的幂该怎么办呢?看下面这个例子:
在这里插入图片描述
最后还剩多少,就设置成多少。

import java.util.*;

public class Main {
    final static int N = 12010;
    static int[] v = new int[N], w = new int[N];
    
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        int cnt = 0;
        for (int i = 0; i < n; ++i) {
            int a = sc.nextInt(), b = sc.nextInt(), s = sc.nextInt();
            int k = 1;
            // k = 1,2,4,...
            while (k <= s) {
                v[cnt] = a * k;
                w[cnt] = b * k;
                s -= k;
                k *= 2;
                cnt++;
            }
            // 如果 s 没有被若干个 k 分完
            if (s > 0) {
                v[cnt] = a * s;
                w[cnt] = b * s;
                cnt++;
            }
        }

        n = cnt;
        int[] dp = new int[m + 1];

        // 01背包模板
        for (int i = 0; i < n; ++i) {
            for (int j = m; j >= v[i]; --j) {
                dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
            }
        }

        System.out.println(dp[m]);
    }
}

分组背包

例题:9. 分组背包问题

在这里插入图片描述

分组背包的枚举顺序为:
每一组 —— 背包容量 —— 每一组中的物品。

import java.util.*;

public class Main {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt(), m = sc.nextInt();
        int[] dp = new int[m + 1];

        List<int[][]> goods = new ArrayList<>();
        for (int i = 0; i < n; ++i) {
            int s = sc.nextInt();
            int[][] ths = new int[s][2];
            for (int j = 0; j < s; ++j) {
                ths[j][0] = sc.nextInt();
                ths[j][1] = sc.nextInt();
            }
            goods.add(ths);
        }
        for (int k = 0; k < n; ++k) {           // 枚举每一组
            int[][] ths = goods.get(k);
            for (int j = m; j >= 0; --j) {      // 枚举背包容量
                for (int[] th : ths) {          // 枚举该组的每一个物品
                    if (j >= th[0]) {
                        dp[j] = Math.max(dp[j], dp[j - th[0]] + th[1]);
                    }
                }
            }
        }
        System.out.println(dp[m]);
    }
}

更多相关内容可见:【算法】01背包和完全背包

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/810549.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023/7/29总结

项目&#xff1a; 这几天主要实现了评论的功能点: 还是有点小bug&#xff0c;还在更改中…… 修改个人中心的界面 接下来是把收藏完善&#xff0c;因为收藏需要用户自己创建一个新的收藏夹

iOS开发-转场动画切换界面(类似系统动画)

iOS开发-转场动画切换界面&#xff08;类似系统动画&#xff09; 在开发中&#xff0c;无论我们使用 push 还是 present 推出新的 viewcontroller 时&#xff0c;系统为了提高用户体验都会为我们默认加上一些过渡动画。但是开发中需要自定义过度动画效果。这里就需要用到了转场…

二十五章:用于弱监督语义分割的激活调节和重新校准方案

0.摘要 图像级弱监督语义分割&#xff08;WSSS&#xff09;是一项基础而具有挑战性的计算机视觉任务&#xff0c;有助于场景理解和自动驾驶。大多数现有方法利用基于分类的类激活图&#xff08;CAMs&#xff09;作为初始伪标签&#xff0c;但这些方法往往关注区分性的图像区域&…

Leetcode刷题---C语言实现初阶数据结构---单链表

1 删除链表中等于给定值 val 的所有节点 删除链表中等于给定值 val 的所有节点 给你一个链表的头节点head和一个整数val&#xff0c;请你删除链表中所有满足Node.valval的节点&#xff0c;并返回新的头节点 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[…

Tomcat 的使用(图文教学)

Tomcat 的使用&#xff08;图文教学&#xff09; 前言一、什么是Tomcat&#xff1f;二、Tomcat 服务器和 Servlet 版本的对应关系三、Tomcat 的使用1、安装2、目录介绍3、如何启动4、Tomcat 的停止5、如何修改 Tomcat 的端口号6、如何部暑 web 工程到 Tomcat 中6.1 方式一6.2 …

建设银行秋招指南,备考技巧和考试内容详解

建设银行秋招简介 银行作为非常吃香的岗位&#xff0c;每年都有不少同学通过投递简历&#xff0c;进入笔试&#xff0c;再到面试成功&#xff0c;成功到银行就职&#xff0c;也有相当一部分同学因为信息差&#xff0c;符合条件却没有报名。无法进入银行工作。 建设银行的秋招…

从保存受限的手机APP中提取文件(读取Android系统中的新增缓存文件)

这个手机APP的权限可能设置了无法在应用内保存文件&#xff0c;但是这个文件实际上一定存在于本地的某个地方&#xff0c;本文的方法通过遍历最后修改日期在今天的文件&#xff0c;很容易就可以找到它。 首先安装一个QPython&#xff0c;这个软件可以允许你在安卓手机上运行Py…

Linux常用命令——dpkg-reconfigure命令

在线Linux命令查询工具 dpkg-reconfigure Debian Linux中重新配制一个已经安装的软件包 补充说明 dpkg-reconfigure命令是Debian Linux中重新配置已经安装过的软件包&#xff0c;可以将一个或者多个已安装的软件包传递给此指令&#xff0c;它将询问软件初次安装后的配置问题…

平板光波导中导模的(注意不是泄露模)传播常数β的matlab计算(验证了是对的)

参照的是导波光学_王建(清华大学)的公式(3-1-2、3-1-3)&#xff0c;算的参数是这本书的图3-3的。 function []PropagationConstantsMain() clear;clc;close all lambda01.55;%真空或空气中的入射波长&#xff0c;单位um k02*pi/lambda0; m3;%导模阶数(需要人为指定) n11.62;%芯…

Godot 4 源码分析 - 动态导入图片文件

用Godot 4尝试编一个电子书软件&#xff0c;初步效果已经出来&#xff0c;并且通过管道通信接口可以获取、设置属性、调用函数&#xff0c;貌似能处理各种事宜了。 其实不然&#xff0c;外因通过内因起作用&#xff0c;如果没把里面搞明白&#xff0c;功能没有开放出来&#x…

Android 13(T) - Media框架(1)- 总览

从事Android Media开发工作三年有余&#xff0c;刚从萌新变成菜鸟&#xff0c;一路上跌跌撞撞学习&#xff0c;看了很多零零碎碎的知识&#xff0c;为了加深对Android Media框架的理解&#xff0c;决定在这里记录下学习过程中想到的一些问题以及一些思考&#xff0c;也希望对初…

国产颗粒更快更稳,价格厚道的光威天策弈系列DDR4内存条值得安排

想要用最少的费用打造出一台性能强悍的电脑&#xff0c;自己动手DIY组装电脑是个更好的选择&#xff0c;特别是今年硬盘和内存方面降价潮此起彼伏&#xff0c;出现了很多神价&#xff0c;高性能内存和硬盘对平台性能提升的效果也是非常显著的。 相比于传统大厂的内存&#xff0…

心法利器[92] | 谈校招:刷题和笔试准备

心法利器 本栏目主要和大家一起讨论近期自己学习的心得和体会&#xff0c;与大家一起成长。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。 2022年新一版的文章合集已经发布&#xff0c;累计已经60w字了&#xff0c;获取方式看这里&…

Linux NUMA架构(非统一内存访问)

NUMA架构 NUMA Architecture| Non Uniform Memory Access Policy/Model | Numa Node Configuration (CPU Affinity) NUMA架构产生的原因 cpu的高速处理功能和内存存储直接的速度会严重影响cpu的性能。传统的计算机单核架构,cpu通过内存总线(内存访问控制器)直接连接到一…

【Linux基础】WSL安装Ubuntu

说明 本文使用的Windows环境是Windows 11 专业版。 WSL现在有二代WSL2&#xff0c;后续都通过WSL2来安装Linux&#xff0c;使用的是Ubuntu发行版&#xff0c;版本是20.04。 安装过程使用了PowerShell&#xff0c;且是管理员权限打开的。 参考适用于 Linux 的 Windows 子系统…

【 Spring AOP学习二】统一功能处理:拦截器异常返回数据格式

目录 一、用户登录权限效验 &#x1f351;1、Spring拦截器实现用户统一登录验证&#xff08;重要&#xff09; &#xff08;1&#xff09;定义一个拦截器 &#xff08;2&#xff09;将自定义拦截器加入到系统配置中 &#x1f351;2、拦截器实现原理 &#x1f351;3、统一…

car tire

汽车轮胎规则参数 小车、轿车轮胎规格参数图解-有驾 半挂车轮胎尺寸多少 货车轮胎尺寸对照表【汽车时代网】

二叉树的最大深度和最小深度(两种方法:递归+迭代)

二叉树的最大深度&#xff1a; class Solution { public:int maxDepth(TreeNode* root) {//DFS 深度优先搜索if(rootNULL) return 0;//深度等于max&#xff08;左子树的深度&#xff0c;右子树的深度&#xff09;1&#xff1b;return max(maxDepth(root->left),maxDepth(roo…

QT自定义控件实现并导入

QT自定义控件 介绍 QT Creator自定义控件和designer控件导入 1.安装QT5.7.1 2.将QT编译器目录、lib目录、include目录导入path 使用说明 使用说明按照 1.创建QtDesigner自定义控件工程&#xff0c;打开Qt Creator,创建一个Qt 设计师自定义控件&#xff0c;如下图所示&#xf…

靠着AI自动生成视频撸自媒体收益,赚了包辣条~

友友们&#xff0c;小卷今天给大家分享下如何通过AI自动生成视频&#xff0c;只需要3分钟就能做出一个视频&#xff0c;把视频发到B站、抖音、西瓜上&#xff0c;还能赚包辣条哦~ 文末给大家准备了AI变现的案例及AIGC知识库&#xff0c;记得领取哦&#xff01; 1.收益 先看看收…