算法打卡day40

今日任务:

1)139.单词拆分

2)多重背包理论基础(卡码网56携带矿石资源)

3)背包问题总结

4)复习day15

139单词拆分

题目链接:139. 单词拆分 - 力扣(LeetCode)

给定一个非空字符串 s 和一个包含非空单词的列表 wordDict,判定 s 是否可以被空格拆分为一个或多个在字典中出现的单词。

说明:
拆分时可以重复使用字典中的单词。你可以假设字典中没有重复的单词。

示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"。

示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以被拆分成 "apple pen apple"。
注意你可以重复使用字典中的单词。

示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

文章讲解:代码随想录 (programmercarl.com)

视频讲解:动态规划之完全背包,你的背包如何装满?| LeetCode:139.单词拆分哔哩哔哩bilibili

思路:

字典里的单词是可以被重复的,这是一个完全背包问题。字符串中的单词是有序的,所以相当于是做排列问题,应该先遍历背包,再遍历物品

这里的s字符串就是背包:创建数组dp[j],不断更新dp[j]的值为True或False。也就是如果s[:j]能拆分,则dp[j] 为True

这里的单词就是物品:我们的目标是检查是否可以将字符串拆分为字典中的单词,这里有两种处理方法,一种是遍历字典中的单词,判断其在背包中能否拆分出来,有一个单词能被拆分都行;另一种是在s[:j]的每一个位置切分,判断s[i:j]是否存在字典中

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        dp = [False] * len(s)
        dp.insert(0, True)
        # print(dp)

        for j in range(1, len(s) + 1):
            for word in wordDict:
                lenth = len(word)
                if j >= lenth:
                    dp[j] = dp[j] or (dp[j-lenth] and word == s[j-lenth : j])
                # print(f'当物品为{word}时,dp[{j}]={dp[j]}')
            # print(f'此时j={j},dp={dp}')
        return dp[-1]

    def wordBreak2(self, s: str, wordDict: List[str]) -> bool:
        # 初始化动态规划数组,dp[j]表示s的前j个字符是否可以被拆分成字典中的单词
        dp = [False] * (len(s)+1)
        dp[0] = True

        # 将字典中的单词转换为集合,便于快速判断单词是否在字典中
        word_set = set(wordDict)

        # 遍历背包
        for j in range(1,len(s)+1):
            # print(f'j={j}')
            # 在背包大小的字符串s[:j]中寻找分割点(s[left:right]左闭右开),看是否存在以s[j]结尾的单词
            for i in range(j+1):
                # print(s[i:j])
                # 如果前i个字符可以被拆分且s[i:j]在字典中,则将dp[j]设置为True
                if s[i:j] in word_set and dp[i]:
                    dp[j] = True
                    break

        # 返回整个字符串s是否可以被拆分
        return dp[-1]

感想:

这题要注意i,j分别在dp和s中表示什么。很容易弄错,自己画图比较清晰
这里有一个优化,我们将字典中的单词转换为集合,便于快速判断单词是否在字典中

假设我们有一个单词列表 wordDict,其中包含了若干个单词。如果我们将这个列表转换为集合 wordSet,则每个单词就会成为 wordSet 中的一个元素。这样,当我们需要判断某个单词是否在字典中时,只需要使用集合的 in 操作符即可。这个操作会以常量时间(O(1))内完成,因为集合底层使用哈希表实现,可以快速地定位元素。

相比之下,如果我们使用列表来表示字典,那么在判断单词是否在字典中时,需要遍历整个列表,时间复杂度会是 O(n),其中 n 是字典中单词的数量。这样的时间复杂度在实际应用中可能会较高,尤其是当字典中包含大量单词时。

因此,将字典中的单词转换为集合后,能够以更高效的方式进行单词的查找,从而加快了判断字符串是否可以被拆分的速度。

多重背包理论基础(卡码网56携带矿石资源)

题目链接:56. 携带矿石资源(第八期模拟笔试) (kamacoder.com)

题目描述
你是一名宇航员,即将前往一个遥远的行星。在这个行星上,有许多不同类型的矿石资源,每种矿石都有不同的重要性和价值。你需要选择哪些矿石带回地球,但你的宇航舱有一定的容量限制。
给定一个宇航舱,最大容量为 C。现在有 N 种不同类型的矿石,每种矿石有一个重量 w[i],一个价值 v[i],以及最多 k[i] 个可用。不同类型的矿石在地球上的市场价值不同。你需要计算如何在不超过宇航舱容量的情况下,最大化你所能获取的总价值。

输入描述
输入共包括四行,第一行包含两个整数 C 和 N,分别表示宇航舱的容量和矿石的种类数量。
接下来的三行,每行包含 N 个正整数。具体如下:
第二行包含 N 个整数,表示 N 种矿石的重量。
第三行包含 N 个整数,表示 N 种矿石的价格。
第四行包含 N 个整数,表示 N 种矿石的可用数量上限。

输出描述
输出一个整数,代表获取的最大价值。

输入示例
10 3
1 3 4
15 20 30
2 3 2

输出示例
90

提示信息
数据范围:
1 <= C <= 10000;
1 <= N <= 10000;
1 <= w[i], v[i], k[i] <= 10000;

文章讲解:代码随想录 (programmercarl.com)

思路:

这个问题可以使用动态规划来解决。我们可以定义一个二维数组 dp[i][j],其中 dp[i][j] 表示前 i 种矿石,容量为 j 的情况下所能获取的最大价值。

具体的动态规划转移方程为:

dp[i][j] = \max(dp[i-1][j], dp[i-1][j - w[i]] + v[i],dp[i-1][j-2*w[i]]+2*v[i],...,dp[i-1][j-k[i]*w[i]]+k[i]*v[i])

其中,dp[i−1][j−w[i]]+v[i] 表示选择了第 i 种矿石,并且当前容量为 j,剩余容量为 j-w[i] 时的最大价值,加上选取当前矿石所获得的价值 v[i]。

根据这个方程,我们可以进行动态规划计算,最终得到dp[N][C],即前 N 种矿石,容量为 C 时所能获取的最大价值。

def max_value():
    # 从键盘上采集输入数据
    C, N = map(int, input().split())  # 宇航舱的容量和矿石的种类数量
    weights = list(map(int, input().split()))  # 矿石的重量
    values = list(map(int, input().split()))  # 矿石的价格
    limits = list(map(int, input().split()))  # 矿石的可用数量上限

    # 创建二维动态规划数组,初始化为0
    dp = [[0] * (C + 1) for _ in range(N + 1)]

    # 遍历每种矿石
    for i in range(1, N + 1):
        # 遍历容量
        for j in range(1, C + 1):
            # 当前容量 j 不足以装下当前矿石 i 时,不选择该矿石
            dp[i][j] = dp[i - 1][j]

            # 遍历当前矿石可用数量上限
            for k in range(1, min(j // weights[i - 1], limits[i - 1]) + 1):
                # 计算选择 k 个当前矿石 i 后的总价值
                dp[i][j] = max(dp[i][j], dp[i - 1][j - k * weights[i - 1]] + k * values[i - 1])

    # 返回前 N 种矿石,容量为 C 时的最大价值
    return dp[N][C]


# 调用函数并输出结果
print(max_value())

这个函数的时间复杂度为 O(N * C * k_max),其中 N 是矿石种类数量,C 是宇航舱的容量,k_max 是矿石的可用数量上限中的最大值。

采用一维dp数组解决,代码如下:

动态转移方程:dp[j] = \max(dp[j], dp[j - k \times weights[i - 1]] + k \times values[i - 1])

其中:

  • dp[j] 表示容量为 j 时的最大价值;
  • weights[i−1] 表示第 i 种矿石的重量;
  • values[i−1] 表示第 i 种矿石的价格;
  • k 表示选择的第 i 种矿石的数量,1\leq k\leq min(\frac{j}{weight[i-1]},limit[i-1])
def max_value2():
    # 从键盘上采集输入数据
    C, N = map(int, input().split())  # 宇航舱的容量和矿石的种类数量
    weights = list(map(int, input().split()))  # 矿石的重量
    values = list(map(int, input().split()))  # 矿石的价格
    limits = list(map(int, input().split()))  # 矿石的可用数量上限

    # 创建一维动态规划数组,初始化为0
    dp = [0] * (C + 1)

    # 遍历每种矿石
    for i in range(1, N + 1):
        # 逆序遍历容量,确保每个矿石只使用一次
        for j in range(C, 0, -1):
            # 遍历当前矿石可用数量上限
            for k in range(1, min(j // weights[i - 1], limits[i - 1]) + 1):
                # 计算选择 k 个当前矿石 i 后的总价值
                dp[j] = max(dp[j], dp[j - k * weights[i - 1]] + k * values[i - 1])

    # 返回容量为 C 时的最大价值
    return dp[C]

# 调用函数并输出结果
print(max_value2())

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

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

相关文章

【数据库原理及应用】期末复习汇总高校期末真题试卷

试卷 一、填空题 1.________是位于用户与操作系统之间的一层数据管理软件。 2.数据库系统的三级模式结构是指________、________、________。 3.数据库系统的三种数据模型是________ 、________、________。 4.若关系中的某一属性组的值能唯一地标识一个元组&#xff0c;则…

项目管理-项目进度管理3/3

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 项目进度管理&#xff1a;需掌握 ITTO, 搞懂计算图&#xff0c;问题和解决方案。 项目进度管理6个过程&#xff0c;包括&#xff08;口…

Qt5.15.2安装Android开发环境。

下载Java 8&#xff0c;不要下Java 20 jdk8 安装跟着默认走就行&#xff1a;C:\Program Files\Java 需要将QtCreator的sdk_definitions.json文件修改一下 “cmdline-tools;latest” 修改为 “cmdline-tools;6.0” 在一个非中文路径&#xff0c;建立一个android-sdk-windows空…

MATLAB 微积分

MATLAB 微积分 MATLAB提供了多种方法来解决微分和积分问题&#xff0c;求解任意程度的微分方程式以及计算极限。最重要的是&#xff0c;您可以轻松求解复杂函数的图&#xff0c;并通过求解原始函数及其导数来检查图上的最大值&#xff0c;最小值和其他文具点。 本章将讨论微…

AD中如何器件带动导线一起旋转

选中器件和导线&#xff0c;右键点击联合&#xff0c;从选中的器件生成联合 点击屏幕右上角的小齿轮&#xff08;设置按钮&#xff09;&#xff0c;选择下图所示的旋转步进为45度&#xff08;或其他&#xff09;&#xff0c;器件拖拽设置为Connected Tracks 之后就可以按住空格…

从零开始搭建一个vue项目

从零开始搭建一个vue项目 一、环境准备 1.1 安装node.js 选择合适的LTS版本&#xff0c;然后下载安装&#xff0c;安装地址&#xff1a;https://nodejs.org/en/download 在命令行中查看已安装的node.js版本 node -v v14.14.01.2 切换为淘宝的镜像源 解决国内下载慢的问题,…

【数据结构(邓俊辉)学习笔记】向量06——位图

文章目录 0.概述1.结构2.实现3. 应用3.1 去重3.2 筛法 0.概述 位图&#xff08;Bitmap&#xff09;是一种特殊的序列结构&#xff0c;可用以动态地表示由一组&#xff08;无符号&#xff09;整数构成的集合。 test() 判断k 是否存在集合S中。set() 将k 加入到集合S中。clear…

免费APP分发平台 - 一个指南和解析

数字化时代的APP分发平台 随着数字化进程的加速免费APP分发平台 - 一个指南和解析&#xff0c;移动应用&#xff08;APP&#xff09;市场正迅速扩大。在这个充满竞争的市场中免费APP分发平台 - 一个指南和解析&#xff0c;一个优秀的APP分发平台能够帮助开发者和商家更有效地触…

【matlab基础知识】(三)二维曲线绘制plot

x[-pi:0.0001:pi]; 选择较小步距 ysin(tan(x))-tan(sin(x));plot(x,y) 条件和函数值做一个点乘 x[-2:0.02:2];y1.1*sign(x).*(abs(x)>1.1)x.*(abs(x)<1.1);plot(x,y) 颜色&#xff0c;线形&#xff0c;曲线上的标志 由于0.01cosx波动太小&#xff0c;所以plotyy绘制多…

蓝桥杯练习系统(算法训练)ALGO-949 勇士和地雷阵

资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 勇士们不小心进入了敌人的地雷阵&#xff08;用n行n列的矩阵表示&#xff0c;*表示某个位置埋有地雷&#xff0c;-表示某个…

可视化大屏C位图:智慧场馆/场所图

Hello&#xff0c;我是大千UI工场&#xff0c;本期可视化大屏的焦点图&#xff08;C位&#xff09;分享将场馆作为焦点图的情形&#xff0c;欢迎友友们关注、评论&#xff0c;如果有订单可私信。 智慧场馆是指通过物联网、大数据、人工智能等技术手段&#xff0c;将传统场馆与…

ctfshow crypto rsa部分题目简单题解

easyrsa1 下载点击打开附件 e 65537 n 1455925529734358105461406532259911790807347616464991065301847 c 69380371057914246192606760686152233225659503366319332065009 题目中给了e,n,c的值。 使用在线网址factordb.com 分解n得到p&#xff0c;q 编写脚本 import gm…

Java项目:基于SSM框架实现的在线医疗服务系统(ssm+B/S架构+源码+数据库+毕业论文+开题报告)

一、项目简介 本项目是一套基于SSM框架实现的在线医疗服务系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、功能…

为什么 IP 地址通常以 192.168 开头?(精简版)

网络通讯的本质就是收发数据包。如果说收发数据包就跟收发快递一样。IP地址就类似于快递上填的收件地址和发件地址一样&#xff0c;路由器就充当快递员的角色&#xff0c;在这个纷繁复杂的网络世界里找到该由谁来接收这个数据包&#xff0c;所以说&#xff1a;IP地址就像快递里…

Java 获取 Outlook 邮箱的日历事件

Java 获取 Outlook 邮箱的日历事件 1.需求描述2.实现方案3.运行结果 IDE&#xff1a;IntelliJ IDEA 2022.3.3 JDK&#xff1a;1.8.0_351 Outlook&#xff1a;Microsoft Office 2016 1.需求描述 比如现在需要获取 Outlook 邮箱中四月的全部的会议安排&#xff0c;如下图所示 …

从零开始搭建Springboot项目脚手架1:新建项目

1、技术栈 SpringBoot 3.2.5&#xff1a; 2、 新建项目 使用SpringInitializr 选择Lombok、Configuration Processor、Spring Web&#xff0c;同时IDEA也要安装Lombok插件 删除多余的Maven目录、Maven文件&#xff0c;把HELP.md改成README.md。 当然前提是已经安装好Maven和配…

【JVM】Java工具(Arthas,APM,Java Agent,JMX)

Java工具 常见的Java工具有以下几类&#xff1a; 1、诊断类工具&#xff0c;如Arthas、VisualVM等。 2、开发类工具&#xff0c;如Idea、Eclipse。 3、APM应用性能监测工具&#xff0c;如Skywalking、Zipkin等。 4、热部署工具&#xff0c;如Jrebel等。 Arthas中 Java Ag…

[笔试训练](十二)

目录 034:删除公共字符串 035:两个链表的第一个公共节点 036:mari和shiny 034:删除公共字符串 删除公共字符_牛客题霸_牛客网 (nowcoder.com) 题解: 用哈希记录好第二个字符串中的字符&#xff0c;再遍历一遍第一个字符串&#xff0c;只将没有记录的字符加在结果字符串上。…

ASP.NET网络在线考试系统

摘 要 随着计算机技术的发展和互联网时代的到来&#xff0c;人们已经进入了信息时代&#xff0c;也有人称为数字化时代。数在数字化的网络环境下&#xff0c;学生希望得到个性化的满足&#xff0c;根据自己的情况进行学习&#xff0c;同时也希望能够得到科学的评价&#xff0c…

文件API及其操作

这里介绍两类文件操作、三个文件类。包括文件系统操作&#xff08;File类&#xff09;、文件内容操作&#xff08;操作字节流、操作字符流&#xff09; 1.文件类File 1.1.认识File类 &#xff08;1&#xff09;什么是File类呢&#xff1f;其实就是可以操作文件的一个类。通过…
最新文章