2024/06/13--代码随想录算法3/17|01背包问题 二维、01背包问题 一维、416. 分割等和子集

在这里插入图片描述
在这里插入图片描述

01背包问题 二维

卡码网链接
在这里插入图片描述

动态规划5步曲

  1. 确定dp数组(dp table)以及下标的含义:dp[i][j] :从下标为[0,i-1]个物品中任取,放进容量为j的背包,价值总和最大为多少。
  2. 确定递推公式,
    有两个方向可以推导出来dp[i][j] :
    不放物品i: dp[i][j] = dp[i - 1][j]
    放物品i: dp[i][j] = dp[i-1][j-weight[i]] + value[i]
    所以递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
  3. dp数组如何初始化 【】
vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));
for (int j = 0 ; j < weight[0]; j++) {  // 当然这一步,如果把dp数组预先初始化为0了,这一步就可以省略,但很多同学应该没有想清楚这一点。
    dp[0][j] = 0;
}
// 正序遍历
for (int j = weight[0]; j <= bagweight; j++) {
    dp[0][j] = value[0];
}
  1. 确定遍历顺序【其实从递归公式: dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]); 可以看出dp[i][j] 是由左上方数值推导出来了,那么 其他下标初始为什么数值都可以,因为都会被覆盖。】
  2. 举例推导dp数组
    先遍历物品,还是先遍历背包都可以,先遍历物品比较简单
def hanshu():
    M, bagweight = [int(x) for x in input().split()]
    weight = [int(x) for x in input().split()]
    value = [int(x) for x in input().split()]
   
    dp = [[0]*(bagweight+1) for i in range(M)]  #dp[i][j]代表从物品【0,i-1】让任意取,背包重量j,达到的最大价值
    #初始化

    for j in range(weight[0],bagweight+1):
        dp[0][j] = value[0]
    for i in range(1, M):
        for j in range(1, bagweight+1):
            if j>=weight[i]:
                dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]]+value[i])
            else:
                dp[i][j] = dp[i-1][j]
        
    return dp[M-1][bagweight]
    
    
maxs = hanshu()
print(maxs)
    

01背包问题 一维(滚动数组)

其实就是遍历物品i的时候,覆盖i-1的结果

动态规划5步曲

  1. 确定dp数组(dp table)以及下标的含义:dp[j] :容量为j的背包,价值总和最大为dp[i]。
  2. 确定递推公式,
    有两个方向可以推导出来dp[i][j] :
    不放物品i: dp[i][j] = dp[i - 1][j]
    放物品i: dp[i][j] = dp[i-1][j-weight[i]] + value[i]
    所以递归公式:此时dp[j]有两个选择,一个是取自己dp[j] 相当于 二维dp数组中的dp[i-1][j],即不放物品i,一个是取dp[j - weight[i]] + value[i],即放物品i,指定是取最大的,毕竟是求最大价值,
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  1. dp数组如何初始化
  2. 确定遍历顺序 倒序遍历背包是为了保证物品i只被放入一次!
    在这里插入图片描述
for(int i = 0; i < weight.size(); i++) { // 遍历物品
    for(int j = bagWeight; j >= weight[i]; j--) { // 遍历背包容量【倒序】
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    }
}
def test_1_wei_bag_problem():
    weight = [1, 3, 4]
    value = [15, 20, 30]
    bagWeight = 4

    # 初始化
    dp = [0] * (bagWeight + 1)
    for i in range(len(weight)):  # 遍历物品
        for j in range(bagWeight, weight[i] - 1, -1):  # 遍历背包容量
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i])

    print(dp[bagWeight])


test_1_wei_bag_problem()

416. 分割等和子集

力扣链接
在这里插入图片描述
要明确本题中我们要使用的是01背包,因为元素我们只能用一次。

回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。
在这里插入图片描述

动态规划5步曲

  1. 确定dp数组(dp table)以及下标的含义:dp[j] :容量为j的背包,价值总和最大为dp[i]。
  2. 确定递推公式,
    有两个方向可以推导出来dp[i][j] :
    不放物品i: dp[i][j] = dp[i - 1][j]
    放物品i: dp[i][j] = dp[i-1][j-weight[i]] + value[i]
    所以递归公式:此时dp[j]有两个选择,一个是取自己dp[j] 相当于 二维dp数组中的dp[i-1][j],即不放物品i,一个是取dp[j - weight[i]] + value[i],即放物品i,指定是取最大的,毕竟是求最大价值,
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
  1. dp数组如何初始化
  2. 确定遍历顺序 倒序遍历背包是为了保证物品i只被放入一次!
    == 如果 dp[j] = j 说明,集合中的子集总和正好可以凑成总和j,理解这一点很重要。==
    主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。
    时间复杂度:O(n^2)
    空间复杂度:O(n)
class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        if sum(nums) % 2 != 0:
            return False
        target = sum(nums) // 2
        dp = [0] * (target + 1)
        for num in nums:
            for j in range(target, num-1, -1):
                dp[j] = max(dp[j], dp[j-num] + num)
        return dp[-1] == target    # 集合中的元素正好可以凑成总和target
class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        
        total_sum = sum(nums)

        if total_sum % 2 != 0:
            return False

        target_sum = total_sum // 2
        dp = [[False] * (target_sum + 1) for _ in range(len(nums) + 1)]

        # 初始化第一行(空子集可以得到和为0)
        for i in range(len(nums) + 1):
            dp[i][0] = True

        for i in range(1, len(nums) + 1):
            for j in range(1, target_sum + 1):
                if j < nums[i - 1]:
                    # 当前数字大于目标和时,无法使用该数字
                    dp[i][j] = dp[i - 1][j]
                else:
                    # 当前数字小于等于目标和时,可以选择使用或不使用该数字
                    dp[i][j] = dp[i - 1][j] or dp[i - 1][j - nums[i - 1]]

        return dp[len(nums)][target_sum]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

简单操作,智能自动化:Windows键鼠模拟软件

一个 Windows 自动化工具&#xff0c;可模拟键盘和鼠标&#xff0c;自动执行任何流程和动作&#xff0c;只需录制动作并运行即可&#xff0c;无需编写脚本&#xff0c;只需按录制&#xff0c;然后播放即可&#xff0c;大小仅 35 KB&#xff0c;且免费无广告。 界面介绍 **打开…

pyside6在QLabel上显示图像文件

猫咪的图片&#xff1a;370*280像素 基本的代码&#xff1a; from PySide6.QtWidgets import QApplication, QLabel, QWidget, QVBoxLayout from PySide6.QtGui import QPixmap, Qtapp QApplication([])widget QWidget() layout QVBoxLayout(widget)label QLabel() label.…

【高校科研前沿】北京大学赵鹏军教授团队在Nature Communications发文:揭示城市人群移动的空间方向性

文章简介 论文名称&#xff1a;Unravelling the spatial directionality of urban mobility 第一作者及单位&#xff1a;赵鹏军&#xff08;教授|第一作者|北京大学&#xff09;&王浩&#xff08;博士生|共同一作|北京大学&#xff09;; 通讯作者及单位&#xff1a;赵鹏军…

计算机网络 —— 运输层(TCP三次握手)

计算机网络 —— 运输层&#xff08;TCP三次握手&#xff09; 三次握手第一次握手第二次握手第三次握手两次握手行不行&#xff1f; 我们今天来学习TCP的三次握手&#xff1a; 三次握手 TCP三次握手是TCP协议中建立连接的过程&#xff0c;旨在确保双方准备好进行可靠的通信。…

JavaScript之函数

函数 使用 声明语法&#xff1a; function 函数名() {函数体 }命名规范&#xff1a; 小驼峰命名法前缀用动词 前缀词&#xff1a; 调用 函数名()函数传参 为了提高函数的灵活性 声明语法&#xff1a; function 函数名(参数列表) {函数体 }调用 函数名(参数)在函数声…

登录/注册- 滑动拼图验证码(IOS/Swift)

本章介绍如何使用ios开发出滑动拼图验证码&#xff0c;分别OC代码和swift代码调用 1.导入项目model文件OC代码&#xff08;下载完整Demo&#xff09; 2.放入你需要显示的图片 一&#xff1a;OC调用 #import "ViewController.h" #import "CodeView.h"…

强大高效,推荐这两款分析文章和抠图的AI工具

ChatDOC ChatDOC是一款基于ChatGPT的AI阅读辅助工具&#xff0c;旨在通过与用户指定的文档进行对话来处理用户的专属数据。它能够帮助用户快速提取文档中的信息&#xff0c;支持多种文件格式&#xff0c;并提供准确的答案。此外&#xff0c;ChatDOC还具备智能格式化、自动摘要生…

使用QT制作QQ登录界面

mywidget.cpp #include "mywidget.h"Mywidget::Mywidget(QWidget *parent): QWidget(parent) {/********制作一个QQ登录界面*********************/this->resize(535,415);//设置登录窗口大小this->setFixedSize(535,415);//固定窗口大小this->setWindowTi…

交换机简介

一、 集线器的替代品—交换机 使用集线器的缺点&#xff0c;因此就设计出了交换机来代替集线器&#xff0c;交换机常见端口数量一般有4、8、16、24、32等数量。 华为交换机&#xff1a;S5720-HI系列 仅从实物图上来看&#xff0c;交换机和集线器非常的像&#xff0c;但是它们的…

【python】通行网格地图四叉树化 (leeccode 427)

【python】通行网格地图四叉树化 受到Leecode 427题的启发&#xff0c;427. 建立四叉树 想将由0和1组成的网格地图绘制为四叉树地图&#xff0c;0表示可通行网格&#xff0c;1表示不可通行网格。 import matplotlib.pyplot as plt import matplotlib.patches as patches …

【ARM Cache 与 MMU/MPU 系列文章 1.2 -- Data Cache 和 Unified Cache 的区别是什么?】

请阅读【ARM Cache 及 MMU/MPU 系列文章专栏导读】 及【嵌入式开发学习必备专栏】 文章目录 Data Cache and Unified Cache数据缓存 (Data Cache)统一缓存 (Unified Cache)数据缓存与统一缓存的比较小结 Data Cache and Unified Cache 在 ARM架构中&#xff0c;缓存&#xff08…

第3章 Unity 3D着色器系统

3.1 从一个外观着色器程序谈起 新建名为basic_diffuse.shader的文件&#xff0c;被一个名为basic_diffuse.mat的材质文件所引用&#xff0c;而basic_diffuse.mat文件则被场景中名为Sphere的game object的MeshRenderer组件所使用。 basic_diffuse.shader代码文件的内容如下所示…

15.RedHat认证-Ansible自动化运维(上)

15.RedHat认证-Ansible自动化运维(上) RHCE8-RH294 Ansible自动化&#xff08;Ansible版本是2.8.2&#xff09; Ansible介绍 1.Ansible是什么&#xff1f; Ansible是一个简单的强大的无代理的自动化运维工具&#xff08;Ansible是自动化运维工具&#xff09;Ansible特点 简…

Java——LinkedList

1、链表 1.1 链表的概念及结构 链表在逻辑层面上是连续的&#xff0c;在物理层面上不一定是连续的 链表结构可分为&#xff0c;单向或双向、带头或不带头、循环或非循环&#xff0c;组合共计8种 重点&#xff1a;无头单向非循环链表、无头双向链表 1.2 模拟实现无头单向非…

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 探测效果(地图探测、地图窥探)

ArcGIS JSAPI 高级教程 - ArcGIS Maps SDK for JavaScript - 探测效果&#xff08;地图探测、地图窥探&#xff09; 实现原理 ArcGIS Maps SDK for JavaScript 从 4.29 开始增加 RenderNode 类&#xff0c;可以添加数据以及操作 FBO&#xff08;ManagedFBO&#xff09;&#xf…

影响数字本振信噪比的因素

2048 点 -66 4096 点-72 8192 点-77 16384 点-84

弃用Docker Desktop:在WSL2中玩转Docker之Docker Engine 部署与WSL入门

Docker技术概论 在WSL2中玩转Docker之Docker Engine部署 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://bl…

Java开发规范

1.接口命名规范–Restful API 原本格式是动词资源by传参&#xff0c;后来进化为Restful API&#xff0c;思想是以资源为中心。 动词用get,post,put,delete请求方法代替&#xff0c;by后面的名词用传参代替。 并且GET方法传参资源ID采用路径传参&#xff0c;除了资源ID外的GET…

区间合并——Acwing.803区间合并

区间合并 定义 区间合并是指将一组有重叠或相邻的区间合并成一个或多个更大的区间。 运用情况 图像处理&#xff1a;在图像的区域分析中&#xff0c;可能需要将相邻的具有相似特征的区域进行合并。时间区间处理&#xff1a;比如将多个连续时间段进行合并。行程规划&#xf…

nodejs湖北省智慧乡村旅游平台-计算机毕业设计源码00232

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;旅游行业当然也不能排除在外。智慧乡村旅游平台是以实际运用为开发背景&#xff0c;运用软件工程开发方法&#xff0c;采…