【每日算法】为啥不是「背包」是「贪心」,以及「贪心解」的正确性证明 |Python 主题月

简介: 【每日算法】为啥不是「背包」是「贪心」,以及「贪心解」的正确性证明 |Python 主题月

网络异常,图片无法展示
|


题目描述



这是 LeetCode 上的 1833. 雪糕的最大数量 ,难度为 中等


Tag : 「贪心」、「排序」


夏日炎炎,小男孩 Tony 想买一些雪糕消消暑。


商店中新到 n 支雪糕,用长度为 n 的数组 costs 表示雪糕的定价,其中 costs[i] 表示第 i 支雪糕的现金价格。


Tony 一共有 coins 现金可以用于消费,他想要买尽可能多的雪糕。


给你价格数组 costs 和现金量 coins,请你计算并返回 Tony 用 coins 现金能够买到的雪糕的 最大数量 。


注意:Tony 可以按任意顺序购买雪糕。


示例 1:


输入:costs = [1,3,2,4,1], coins = 7
输出:4
解释:Tony 可以买下标为 0、1、2、4 的雪糕,总价为 1 + 3 + 2 + 1 = 7
复制代码


示例 2:


输入:costs = [10,6,8,7,7,8], coins = 5
输出:0
解释:Tony 没有足够的钱买任何一支雪糕。
复制代码


示例 3:
输入:costs = [1,6,3,1,2,5], 
输出:6
解释:Tony 可以买下所有的雪糕,总价为 1 + 6 + 3 + 1 + 2 + 5 = 18 。
复制代码


提示:


  • costs.length == n
  • 1 <= n <= 10^5105
  • 1 <= costs[i] <= 10^5105
  • 1 <= coins <= 10^8108


基本分析



从题面看,是一道「01 背包」问题,每个物品的成本为 cost[i]cost[i],价值为 11


但「01 背包」的复杂度为 O(N* C)O(NC),其中 NN 为物品数量(数量级为 10^5105),CC 为背包容量(数量级为 10^8108)。显然会 TLE。


换个思路发现,每个被选择的物品对答案的贡献都是 11,优先选择价格小的物品会使得我们剩余金额尽可能的多,将来能够做的决策方案也就相应变多。


因此一个直观的做法是,对物品数组进行「从小到大」排序,然后「从前往后」开始决策购买。


证明



直观上,这样的贪心思路可以使得最终选择的物品数量最多。


接下来证明一下该思路的正确性。


假定贪心思路取得的序列为 [a1,a2,a3,...,an][a1,a2,a3,...,an](长度为 nn),真实最优解所取得的序列为 [b1,b2,b3,..,bm][b1,b2,b3,..,bm](长度为 mm)。


两个序列均为「单调递增序列」。


其中最优解所对应具体方案不唯一,即存在多种选择方案使得物品数量相同。


因此,我们只需要证明两个序列长度一致即可


按照贪心逻辑,最终选择的方案总成本不会超过 coinscoins,因此至少是一个合法的选择方案,天然有 n \leq mnm,只需要证明 n \geq mnm 成立,即可得证 n = mn=m


通过反证法证明 n \geq mnm 成立,假设 n \geq mnm 不成立,即有 n < mn<m


根据贪心决策,我们选择的物品序列在「排序好的 costcost 数组」里,必然是一段连续的前缀。并且再选择下一物品将会超过总费用 coinscoins;而真实最优解的选择方案在「排序好的 costcost 数组」里分布不定。


网络异常,图片无法展示
|


这时候我们可以利用「每个物品对答案的贡献均为 11,将最优解中的分布靠后的物品,替换为分布较前的物品,不会使得费用增加,同时答案不会变差」。


从而将真实最优解也调整为某段连续的前缀。


网络异常,图片无法展示
|


综上,通过反证法得证 n \geq mnm 成立,结合 n \leq mnm,可推出 n = mn=m


即贪心解必然能够取得与最优解一样的长度。


贪心



排序,从前往后决策,直到不能决策为止。


代码:


class Solution:
    def maxIceCream(self, costs: List[int], coins: int) -> int:
        n = len(costs)
        costs.sort()
        ans = 0
        for i in range(n):
            if coins >= costs[i]:
                ans += 1
                coins -= costs[i]
        return ans
复制代码


  • 时间复杂度:排序复杂度为 O(n\log{n})O(nlogn);获取答案的复杂度为 O(n)O(n)。整体复杂度为 O(n\log{n})O(nlogn)
  • 空间复杂度:排序复杂度为 O(\log{n})O(logn)。整体复杂度为 O(\log{n})O(logn)


PS. 这里假定 Arrays.sort 使用的是「双轴排序」的实现。


更多与「贪心/相信科学系列」相关内容



所有的「贪心题」都有严格证明;不是「贪心题」,需要证明的地方也会有证明。


请放心食用 🤣 🤣



最后



这是我们「刷穿 LeetCode」系列文章的第 No.1833 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。


在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。


为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…


在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。

相关文章
|
14天前
|
机器学习/深度学习 算法 TensorFlow
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
动物识别系统。本项目以Python作为主要编程语言,并基于TensorFlow搭建ResNet50卷积神经网络算法模型,通过收集4种常见的动物图像数据集(猫、狗、鸡、马)然后进行模型训练,得到一个识别精度较高的模型文件,然后保存为本地格式的H5格式文件。再基于Django开发Web网页端操作界面,实现用户上传一张动物图片,识别其名称。
46 1
动物识别系统Python+卷积神经网络算法+TensorFlow+人工智能+图像识别+计算机毕业设计项目
|
14天前
|
机器学习/深度学习 人工智能 算法
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
植物病害识别系统。本系统使用Python作为主要编程语言,通过收集水稻常见的四种叶片病害图片('细菌性叶枯病', '稻瘟病', '褐斑病', '稻瘟条纹病毒病')作为后面模型训练用到的数据集。然后使用TensorFlow搭建卷积神经网络算法模型,并进行多轮迭代训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地模型文件。再使用Django搭建Web网页平台操作界面,实现用户上传一张测试图片识别其名称。
65 21
植物病害识别系统Python+卷积神经网络算法+图像识别+人工智能项目+深度学习项目+计算机课设项目+Django网页界面
|
14天前
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
60 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
13天前
|
机器学习/深度学习 算法 TensorFlow
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
交通标志识别系统。本系统使用Python作为主要编程语言,在交通标志图像识别功能实现中,基于TensorFlow搭建卷积神经网络算法模型,通过对收集到的58种常见的交通标志图像作为数据集,进行迭代训练最后得到一个识别精度较高的模型文件,然后保存为本地的h5格式文件。再使用Django开发Web网页端操作界面,实现用户上传一张交通标志图片,识别其名称。
43 6
交通标志识别系统Python+卷积神经网络算法+深度学习人工智能+TensorFlow模型训练+计算机课设项目+Django网页界面
|
9天前
|
机器学习/深度学习 人工智能 算法
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
文本分类识别系统。本系统使用Python作为主要开发语言,首先收集了10种中文文本数据集("体育类", "财经类", "房产类", "家居类", "教育类", "科技类", "时尚类", "时政类", "游戏类", "娱乐类"),然后基于TensorFlow搭建CNN卷积神经网络算法模型。通过对数据集进行多轮迭代训练,最后得到一个识别精度较高的模型,并保存为本地的h5格式。然后使用Django开发Web网页端操作界面,实现用户上传一段文本识别其所属的类别。
22 1
【新闻文本分类识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
25天前
|
前端开发 搜索推荐 算法
中草药管理与推荐系统Python+Django网页界面+推荐算法+计算机课设系统+网站开发
中草药管理与推荐系统。本系统使用Python作为主要开发语言,前端使用HTML,CSS,BootStrap等技术和框架搭建前端界面,后端使用Django框架处理应用请求,使用Ajax等技术实现前后端的数据通信。实现了一个综合性的中草药管理与推荐平台。具体功能如下: - 系统分为普通用户和管理员两个角色 - 普通用户可以登录,注册、查看物品信息、收藏物品、发布评论、编辑个人信息、柱状图饼状图可视化物品信息、并依据用户注册时选择的标签进行推荐 和 根据用户对物品的评分 使用协同过滤推荐算法进行推荐 - 管理员可以在后台对用户和物品信息进行管理编辑
57 12
中草药管理与推荐系统Python+Django网页界面+推荐算法+计算机课设系统+网站开发
|
7天前
|
大数据 UED 开发者
实战演练:利用Python的Trie树优化搜索算法,性能飙升不是梦!
在数据密集型应用中,高效搜索算法至关重要。Trie树(前缀树/字典树)通过优化字符串处理和搜索效率成为理想选择。本文通过Python实战演示Trie树构建与应用,显著提升搜索性能。Trie树利用公共前缀减少查询时间,支持快速插入、删除和搜索。以下为简单示例代码,展示如何构建及使用Trie树进行搜索与前缀匹配,适用于自动补全、拼写检查等场景,助力提升应用性能与用户体验。
22 2
|
11天前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
在 Python 编程中,算法的性能至关重要。本文将带您深入了解算法复杂度的概念,包括时间复杂度和空间复杂度。通过具体的例子,如冒泡排序算法 (`O(n^2)` 时间复杂度,`O(1)` 空间复杂度),我们将展示如何评估算法的性能。同时,我们还会介绍如何优化算法,例如使用 Python 的内置函数 `max` 来提高查找最大值的效率,或利用哈希表将查找时间从 `O(n)` 降至 `O(1)`。此外,还将介绍使用 `timeit` 模块等工具来评估算法性能的方法。通过不断实践,您将能更高效地优化 Python 程序。
28 4
|
9天前
|
机器学习/深度学习 人工智能 算法
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台。果蔬识别系统,本系统使用Python作为主要开发语言,通过收集了12种常见的水果和蔬菜('土豆', '圣女果', '大白菜', '大葱', '梨', '胡萝卜', '芒果', '苹果', '西红柿', '韭菜', '香蕉', '黄瓜'),然后基于TensorFlow库搭建CNN卷积神经网络算法模型,然后对数据集进行训练,最后得到一个识别精度较高的算法模型,然后将其保存为h5格式的本地文件方便后期调用。再使用Django框架搭建Web网页平台操作界面,实现用户上传一张果蔬图片识别其名称。
28 0
【果蔬识别系统】Python+卷积神经网络算法+人工智能+深度学习+计算机毕设项目+Django网页界面平台
|
13天前
|
缓存 算法 数据处理
时间&空间复杂度,Python 算法的双重考验!如何优雅地平衡两者,打造极致性能?
在Python算法中,时间与空间复杂度的平衡至关重要。时间复杂度反映算法执行时间随输入规模的变化趋势,空间复杂度则关注额外存储空间的需求。优秀的算法需兼顾两者,如线性搜索时间复杂度为O(n),空间复杂度为O(1);二分查找在时间效率上显著提升至O(log n),空间复杂度保持为O(1);动态规划通过牺牲O(n)空间换取O(n)时间内的高效计算。实际应用中,需根据具体需求权衡,如实时数据处理重视时间效率,而嵌入式系统更关注空间节约。通过不断优化,我们能在Python中找到最佳平衡点,实现高性能程序。
34 3
下一篇
无影云桌面