9.8分割等和子集(LC416-M)

2024-03-04 03:36
文章标签 分割 子集 9.8 lc416

本文主要是介绍9.8分割等和子集(LC416-M),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法:

可以转换为背包问题:

一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,写法还是不一样的。

要明确本题中我们要使用的是01背包,因为元素我们只能用一次。

只有确定了如下四点,才能把01背包问题套到本题上来。

  • 背包的体积为sum / 2
  • 背包要放入的商品:集合里的元素。重量为 元素的数值,价值也为元素的数值
  • 背包如果正好装满,说明找到了总和为 sum / 2 的子集。
  • 背包中每一个元素不可重复放入。

动规五步曲:

1.确定dp数组及其下标:

01背包中,dp[j] 表示: 容量为j的背包,所背的物品价值最大可以为dp[j]。

本题:dp[j]表示 背包总容量(所能装的总重量)是j,放进物品后,背的最大重量为dp[j]

2.确定递推公式:

01背包的递推公式为:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

本题,相当于背包里放入数值,那么物品i的重量是nums[i],其价值也是nums[i]。

所以递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);

3.dp初始化:

从dp[j]的定义来看,dp[0]一定是0。

如果题目给的价值都是正整数那么非0下标都初始化为0就可以了,如果题目给的价值有负数,那么非0下标就要初始化为负无穷。

这样才能让dp数组在递推的过程中取得最大的价值,而不是被初始值覆盖了

4.确定遍历顺序:

01背包如果使用一维dp数组,物品遍历的for循环放在外层,遍历背包的for循环放在内层,且内层for循环倒序遍历!

// 开始 01背包
for(int i = 0; i < nums.size(); i++) {for(int j = target; j >= nums[i]; j--) { // 每一个元素一定是不可重复放入,所以从大到小遍历dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);}
}

5.举例推导dp

dp[j]的数值一定是小于等于j的。

如果dp[j] == j 说明,集合中的子集总和正好可以凑成总和j,理解这一点很重要。

dp[j] = max(dp[j], dp[j - nums[i]] + nums[i])

    • `dp` 数组初始化为 `[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`(长度为 `target + 1`,即 12)。
    • `i = 0``nums[0] = 1`
      • 内层循环从 `target`(11)到 `nums[0]`(1):
        • `j = 11``dp[11] = Math.max(0, dp[11 - 1] + 1) = 1`
        • `j = 10``dp[10] = Math.max(0, dp[10 - 1] + 1) = 1`
        • `j = 5``dp[5] = Math.max(0, dp[5 - 1] + 1) = 1`
        • `j = 1``dp[1] = Math.max(0, dp[1 - 1] + 1) = 1`
    • `i = 1``nums[1] = 5`
      • 内层循环从 `target`(11)到 `nums[1]`(5):
        • `j = 11``dp[11] = Math.max(1, dp[11 - 5] + 5) = 6`
        • `j = 10``dp[10] = Math.max(1, dp[10 - 5] + 5) = 6`
        • `j = 5``dp[5] = Math.max(1, dp[5 - 5] + 5) = 6`
        • `j = 1``dp[1] = Math.max(1, dp[1 - 5] + 5) = 5`
    • `i = 2``nums[2] = 11`
      • 内层循环从 `target`(11)到 `nums[2]`(11):
        • `j = 11``dp[11] = Math.max(6, dp[11 - 11] + 11) = 11`
        • `j = 10``dp[10] = Math.max(6, dp[10 - 11] + 11) = 11`
        • `j = 5``dp[5] = Math.max(6, dp[5 - 11] + 11) = 11`
        • `j = 1``dp[1] = Math.max(6, dp[1 - 11] + 11) = 11`
    • `i = 3``nums[3] = 5`
      • 内层循环从 `target`(11)到 `nums[3]`(5):
        • `j = 11``dp[11] = Math.max(11, dp[11 - 5] + 5) = 11`
        • `j = 10``dp[10] = Math.max(11, dp[10 - 5] + 5) = 11`
        • `j = 5``dp[5] = Math.max(11, dp[5 - 5] + 5) = 11`
        • `j = 1``dp[1] = Math.max(11, dp[1 - 5] + 5) = 11`

由于在 `i = 3` 时 `dp[target] == target`,所以最终返回 `true`

正确代码:

class Solution {public boolean canPartition(int[] nums) {int sum = 0;//求和for(int a=0; a<nums.length; a++){sum += nums[a];}//若sum为奇数,无法等分if (sum % 2 != 0) return false;//求targetint target = sum/2;int[] dp = new int[target+1];//dp初始化,所有值都为0(就算不初始化,java也会自动把int数组初始化为0)for (int i=0; i<dp.length;i++){dp[i]=0;}for(int i = 0; i<nums.length; i++){for(int j=target; j>=nums[i]; j--){dp[j] = Math.max(dp[j], dp[j-nums[i]]+nums[i]);}}//若背包装满了,return truereturn dp[target] == target;}}

注意:

1.使用sum时,要将sum初始化:int sum = 0;

2.求target之前,要考虑sum能不能被等分

3.dp数组的长度为target+1

4.for循环时j>=nums[i]

大于等于!

 `j>=nums[i]` 时,考虑的是包括当前物品的情况,因为想要确保当前物品可以放入背包中。

如果使用 `j>nums[i]`,那么就会漏掉考虑将当前物品放入背包的情况,因为此时不包括当前物品的情况也会被考虑到。

5.函数的返回值是bool,所以最后return dp[target] == target;

6.如果将数组 `dp` 的初始化部分注释掉,代码仍然能够正常工作

Java中对于未显式初始化的数组,会自动将数组的元素初始化为默认值。

对于基本数据类型 `int`,其默认值为0。因此,当创建一个 `int` 类型的数组时,如果没有显式地对数组进行初始化,Java会自动将数组的元素初始化为0。

时间空间复杂度:

  • 时间复杂度:O(n^2)

  • 空间复杂度:O(n),虽然dp数组大小为一个常数,但是大常数

这篇关于9.8分割等和子集(LC416-M)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/771881

相关文章

9.8javaweb项目总结

1.主界面用户信息显示 登录成功后,将用户信息存储在记录在 localStorage中,然后进入界面之前通过js来渲染主界面 存储用户信息 将用户信息渲染在主界面上,并且头像设置跳转,到个人资料界面 这里数据库中还没有设置相关信息 2.模糊查找 检测输入框是否有变更,有的话调用方法,进行查找 发送检测请求,然后接收的时候设置最多显示四个类似的搜索结果

SAM2POINT:以zero-shot且快速的方式将任何 3D 视频分割为视频

摘要 我们介绍 SAM2POINT,这是一种采用 Segment Anything Model 2 (SAM 2) 进行零样本和快速 3D 分割的初步探索。 SAM2POINT 将任何 3D 数据解释为一系列多向视频,并利用 SAM 2 进行 3D 空间分割,无需进一步训练或 2D-3D 投影。 我们的框架支持各种提示类型,包括 3D 点、框和掩模,并且可以泛化到不同的场景,例如 3D 对象、室

GitHub每周最火火火项目(9.2-9.8)

项目名称:polarsource / polar 项目介绍:polar 是一个开源项目,它是 Lemon Squeezy 的替代方案,并且具有更具优势的价格。该项目的目标是为开发者提供一种更好的选择,让他们能够在追求自己的热情和兴趣的同时,通过编码获得相应的报酬。通过使用 polar,开发者可以享受到更实惠的价格,同时也能够更自由地发挥自己的创造力和技能。 项目地址:https://github.

码蹄集部分题目(2024OJ赛9.4-9.8;线段树+树状数组)

1🐋🐋配对最小值(王者;树状数组) 时间限制:1秒 占用内存:64M 🐟题目思路 MT3065 配对最小值_哔哩哔哩_bilibili 🐟代码 #include<bits/stdc++.h> using namespace std;const int N=1e5+7;int a[N],b[N],c[N],n,q;struct QUERY{int l,r,id;}que

9.8通宵速通javascript

由于正着已经光速通了一些基础语法了,所以这一步我们倒着来。并记录一些疑问从而从难到易去解决这些问题。 23 eventloop 首先明确两个概念,分别是 1 调用栈 javascript只有一个调用栈用于跟踪函数其他的就类似于任何语言的函数调用栈 2 任务队列 异步任务在完成时会被添加到任务队列中,当调用栈为空的时候,也就是当下的函数全部执行完之后,会将这些已经完成的任务从任务队列中放入函数调

基于YOLO8的图片实例分割系统

文章目录 在线体验快速开始一、项目介绍篇1.1 YOLO81.2 ultralytics1.3 模块介绍1.3.1 scan_task1.3.2 scan_taskflow.py1.3.3 segment_app.py 二、核心代码介绍篇2.1 segment_app.py2.2 scan_taskflow.py 三、结语 代码资源:计算机视觉领域YOLO8技术的图片实例分割实

如何将卷积神经网络(CNN)应用于医学图像分析:从分类到分割和检测的实用指南

引言 在现代医疗领域,医学图像已经成为疾病诊断和治疗规划的重要工具。医学图像的类型繁多,包括但不限于X射线、CT(计算机断层扫描)、MRI(磁共振成像)和超声图像。这些图像提供了对身体内部结构的详细视图,有助于医生在进行准确诊断和制定个性化治疗方案时获取关键的信息。 1. 医学图像分析的挑战 医学图像分析面临诸多挑战,其中包括: 图像数据的复杂性:医学图像通常具有高维度和复杂的结构

代码随想录刷题day24丨93.复原IP地址 ,78.子集 , 90.子集II

代码随想录刷题day24丨93.复原IP地址 ,78.子集 , 90.子集II 1.题目 1.1复原IP地址 题目链接:93. 复原 IP 地址 - 力扣(LeetCode) 视频讲解:回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0093.%E5%A4%8

图像分割分析效果2

这次加了结构化损失 # 训练集dice: 0.9219 - iou: 0.8611 - loss: 0.0318 - mae: 0.0220 - total: 0.8915  # dropout后:dice: 0.9143 - iou: 0.8488 - loss: 0.0335 - mae: 0.0236 - total: 0.8816 # 加了结构化损失后:avg_score: 0.89