当前位置: 首页 > article >正文

力扣力扣力:860柠檬水找零

860. 柠檬水找零 - 力扣(LeetCode)

需要注意的是,我们一开始是没有任何钱的,也就是说我们需要拿着顾客的钱去找零。如果第一位顾客上来就是要找零那么我们无法完成,只能返回false。

分析:

上来我们先不分析贪心算法的内容,先进行一个简单的分类讨论:

1.顾客给一张5块

我们直接收下即可,无需找零

2.顾客给一张10块

我们收下10块并且还需要找零5块

3.顾客给一张20块

我们有两种找零策略:

1)给一张10块加上一张5块

2)给三张5块

所以我们可以看到决定一个顾客是否能成功找零的关键原因就是我们是否有足够多的5块。所以如果我们遇到情况3也就是顾客给了20块的时候,我们应该优先考虑将10块钱先花出去,尽可能的保留多的5块,选择第一种方案。否则就可能遇到找不过来的情况,例如考虑以下两个顾客先后来买,第一个给了20,第二个给了10块。如果我们选择了给三张5块那么就无法找零第二个顾客了。这也是贪心策略在这里的体现,在我们完整的思考过后,其实一般贪心的代码都很好写。

实现:

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int five = 0,ten = 0;
        for(auto x : bills)
        {
            if(x == 5) five++;
            else if(x == 10)
            {
                if(five == 0) return false;
                five--;ten++;
            }
            else
            {
                if(five && ten)
                {
                    ten--;five--;
                }
                else if(five >= 3)
                {
                    five-=3;
                }
                else return false;
            }
        }
        return true;
    }
};

最后我们来证明以下,这个贪心算法的正确性:

这里我们会用到一个新的证明方法:

交换论证法的步骤:

交换论证法是一种用来证明贪心算法正确性的技巧,主要思路是:

  1. 假设当前解不是贪心算法的解;
  2. 如果可以通过交换某些决策将其变成贪心算法的解且不劣化最终结果,则证明贪心解是最优解。
  • 贪心策略的设计目标:

    • 贪心的核心在于每次找零时优先保存更小面值(尤其是 5 美元)的纸币,因为更小面值的纸币在后续找零中更灵活。
  • 假设非贪心策略:

    • 如果在某次找零时,没有遵循贪心策略,而是选择了更大的面值(如直接用 3 张 5 美元替代了 10 美元找零)。
    • 我们通过交换操作尝试将非贪心解调整为贪心解。
  • 交换操作:

    • 假设在支付 20 美元时:
      • 非贪心策略使用了 3 张 5 美元找零;
      • 贪心策略建议使用 1 张 10 美元和 1 张 5 美元找零。
    • 如果后续再遇到需要支付 20 美元的顾客,而没有足够的 10 美元,则可能无法完成找零。
    • 通过将之前的 3 张 5 美元找零改为 1 张 10 美元和 1 张 5 美元找零,确保后续支付的灵活性不下降。
  • 无损性:

    • 贪心策略的交换操作不会导致当前的找零失败,同时提高了剩余零钱的灵活性。
  • 归纳证明:

    • 对于每个顾客的支付:
      • 如果选择贪心策略找零,剩余的零钱会是当前最优的(灵活性最大化)。
      • 假设前 k−1 个顾客都满足贪心策略的正确性,那么第 k个顾客支付时,贪心策略也能保证正确性。

http://www.kler.cn/a/408940.html

相关文章:

  • Java---反射机制
  • vue实现滚动下拉加载更多
  • [SUCTF2019]SignIn
  • 测试实项中的偶必现难测bug之模糊匹配逻辑
  • 高级网络安全——SSL/TLS, HTTPS, VPN(week4)
  • 若依-一个请求中返回多个表的信息
  • 【机器学习监督学习】:从原理到实践,探索算法奥秘,揭示数据标注、模型训练与预测的全过程,助力人工智能技术应用与发展
  • Unity 内置枚举(Option Stencil)
  • 【AI技术赋能有限元分析应用实践】Abaqus、 Ansys、FEniCSx 有限元结合深度学习
  • Java爬虫与淘宝API接口:深度解析销量和商品详情数据获取
  • FMCJ456-14bit 2通道3/2.6/2GS/s ADC +16bit 2通道12.6GS/s DAC FMC AD/DA子卡
  • 网站渗透测试工具zap2docker-stable
  • H.264/H.265播放器EasyPlayer.js网页全终端安防视频流媒体播放器关于iOS不能系统全屏
  • 第425场周赛题解:最小正和子数组
  • Fakelocation Server服务器/专业版 Centos7
  • 图形渲染性能优化
  • python中lxml 库之 etree 使用详解
  • Sparrow系列拓展篇:消息队列和互斥锁等IPC机制的设计
  • Go 语言中的海勒姆定律
  • Jenkins-Git Parameter 插件实现指定版本的发布和回滚
  • 解释 Python 中的可变与不可变数据类型?
  • 框架学习07 - SpringMVC 地址映射
  • Sqlite: Java使用、sqlite-devel
  • 深度学习图像视觉 RKNN Toolkit2 部署 RK3588S边缘端 过程全记录
  • 初识算法 · 分治(3)
  • Excel求和如何过滤错误值