算法打卡day40

news2025/1/13 15:56:07

今日任务:

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.coloradmin.cn/o/1641384.html

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

相关文章

【22-处理不平衡数据集:Scikit-learn中的技术和策略】

文章目录 前言了解不平衡数据集重采样技术过采样欠采样生成合成样本调整类别权重使用适合于不平衡数据集的评估指标结论前言 在机器学习任务中,不平衡数据集是一个非常常见的问题。它指的是数据集中各类别样本数量差异较大,这种情况在现实世界的数据收集中非常普遍,特别是在…

WebDriver使用带用户名密码验证的IP代理解决方案

背景&#xff0c;使用python3 selenium 先定义一个方法&#xff0c;这里主要用到了chrome插件的功能&#xff0c;利用这个插件来放进代理内容。 def create_proxy_auth_extension(proxy_host, proxy_port,proxy_username, proxy_password, schemehttp):manifest_json "…

专业渗透测试 Phpsploit-Framework(PSF)框架软件小白入门教程(一)

本系列课程&#xff0c;将重点讲解Phpsploit-Framework框架软件的基础使用&#xff01; 本文章仅提供学习&#xff0c;切勿将其用于不法手段&#xff01; Phpsploit-Framework&#xff08;简称 PSF&#xff09;框架软件&#xff0c;是一款什么样的软件呢&#xff1f; Phpspl…

开源的贴吧数据查询工具

贴吧数据查询工具 这是一个贴吧数据查询工具&#xff0c;目前仍处于开发阶段。 本地运行 要本地部署这个项目&#xff0c;请 克隆这个仓库并前往项目目录 git clone https://github.com/Dilettante258/tieba-tools.git cd tieba-tools安装依赖 pnpm install运行项目 np…

如何配置Jupyter Lab以允许远程访问和设置密码保护

如何配置Jupyter Lab以允许远程访问和设置密码保护 当陪你的人要下车时&#xff0c;即使不舍&#xff0c;也该心存感激&#xff0c;然后挥手道别。——宫崎骏《千与千寻》 在数据科学和机器学习工作流中&#xff0c;Jupyter Lab是一个不可或缺的工具&#xff0c;但是默认情况下…

《金融研究》:普惠金融改革试验区DID工具变量数据(2012-2023年)

数据简介&#xff1a;本数据集包括普惠金融改革试验区和普惠金融服务乡村振兴改革试验区两类。 其中&#xff0c;河南兰考、浙江宁波、福建龙岩和宁德、江西赣州和吉安、陕西铜川五省七地为普惠金融改革试验区。山东临沂、浙江丽水、四川成都三地设立的是普惠金融服务乡村振兴…

《Mask2Former》算法详解

文章地址&#xff1a;《Masked-attention Mask Transformer for Universal Image Segmentation》 代码地址&#xff1a;https://github.com/facebookresearch/Mask2Former 文章为发表在CVPR2022的一篇文章。从名字可以看出文章像提出一个可以统一处理各种分割任务&#xff08;…

C++学习第二十二课:STL映射类的深入解析

C学习第二十二课&#xff1a;STL映射类的深入解析 在C标准模板库&#xff08;STL&#xff09;中&#xff0c;映射类&#xff08;std::map和std::multimap&#xff09;是用来存储关联数据的容器。与集合类不同&#xff0c;映射类中的每个元素都是一个键值对&#xff08;key-val…

十四、网络编程

目录 一、二、网络通讯要素三、IP和端口号四、网络协议1、网络通信协议2、TCP/IP协议簇1&#xff09;TCP协议2&#xff09;UDP 3、Socket 五、TCP网络编程1、基于Socket的TCP编程1&#xff09;客户端创建socket对象2&#xff09; 服务器端建立 ServerSocket对象 2、UDP网络通信…

17 内核开发-内核内部内联汇编学习

​ 17 内核开发-内核内部内联汇编学习 课程简介&#xff1a; Linux内核开发入门是一门旨在帮助学习者从最基本的知识开始学习Linux内核开发的入门课程。该课程旨在为对Linux内核开发感兴趣的初学者提供一个扎实的基础&#xff0c;让他们能够理解和参与到Linux内核的开发过程中…

【 书生·浦语大模型实战营】学习笔记(六):Lagent AgentLego 智能体应用搭建

&#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料&#xff0c;配有全面而有深度的专栏内容&#xff0c;包括不限于 前沿论文解读、…

MySQL技能树学习——数据库组成

数据库组成&#xff1a; 数据库是一个组织和存储数据的系统&#xff0c;它由多个组件组成&#xff0c;这些组件共同工作以确保数据的安全、可靠和高效的存储和访问。数据库的主要组成部分包括&#xff1a; 数据库管理系统&#xff08;DBMS&#xff09;&#xff1a; 数据库管理系…

node.js中path模块-路径处理,语法讲解

node中的path 模块是node.js的基础语法&#xff0c;实际开发中&#xff0c;我们通过使用 path 模块来得到绝对路径&#xff0c;避免因为相对路径带来的找不到资源的问题。 具体来说&#xff1a;Node.js 执行 JS 代码时&#xff0c;代码中的路径都是以终端所在文件夹出发查找相…

服务器被攻击,为什么后台任务管理器无法打开?

在服务器遭受DDoS攻击后&#xff0c;当后台任务管理器由于系统资源耗尽无法打开时&#xff0c;管理员需要依赖间接手段来进行攻击类型的判断和解决措施的实施。由于涉及真实代码可能涉及到敏感操作&#xff0c;这里将以概念性伪代码和示例指令的方式来说明。 判断攻击类型 步…

DHCPv4_CLIENT_ALLOCATING_04: 发送DHCPREQUEST - 头部值‘secs‘字段

测试目的&#xff1a; 验证客户端发送的DHCPREQUEST消息是否使用了与原始DHCPDISCOVER消息相同的’secs’字段值。 描述&#xff1a; 本测试用例旨在确保DHCP客户端在发送DHCPREQUEST消息时&#xff0c;使用了与它之前发送的DHCPDISCOVER消息相同的’secs’字段值。这是DHCP…

国产数据库的发展势不可挡

前言 新的一天又开始了&#xff0c;光头强强总不紧不慢地来到办公室&#xff0c;准备为今天一天的工作&#xff0c;做一个初上安排。突然&#xff0c;熊二直接进入办公室&#xff0c;说&#xff1a;“强总老大&#xff0c;昨天有一个数据库群炸了锅了&#xff0c;有一位姓虎的…

【LLM 论文】UPRISE:使用 prompt retriever 检索 prompt 来让 LLM 实现 zero-shot 解决 task

论文&#xff1a;UPRISE: Universal Prompt Retrieval for Improving Zero-Shot Evaluation ⭐⭐⭐⭐ EMNLP 2023, Microsoft Code&#xff1a;https://github.com/microsoft/LMOps 一、论文速读 这篇论文提出了 UPRISE&#xff0c;其思路是&#xff1a;训练一个 prompt retri…

Git可视化工具tortoisegit 的下载与使用

一、tortoisegit 介绍 TortoiseGit 是一个非常实用的版本控制工具&#xff0c;主要用于与 Git 版本控制系统配合使用。 它的主要特点包括&#xff1a; 图形化界面&#xff1a;提供了直观、方便的操作界面&#xff0c;让用户更易于理解和管理版本控制。与 Windows 资源管理器…

Flutter笔记:Widgets Easier组件库(9)使用弹窗

Flutter笔记 Widgets Easier组件库&#xff08;9&#xff09;&#xff1a;使用弹窗 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress o…

美国站群服务器的定义、功能以及在网站运营中的应用

美国站群服务器的定义、功能以及在网站运营中的应用 在当今互联网的蓬勃发展中&#xff0c;站群服务器已成为网站运营和SEO优化中不可或缺的重要工具之一。尤其是美国站群服务器&#xff0c;在全球范围内备受关注。本文将深入探讨美国站群服务器的定义、功能以及在网站运营中的…