双“11”搞促销?用贪心算法来盘他!

作者 | 王磊

来源 | Java中文社群(ID:javacn666)

转载请联系授权(微信ID:GG_Stone)

这几年商家为了刺激消费是变着花样的推出各种各样的活动,以某多多为首的运营式电商更是让我们看到了营销的无限“潜力”。

这不,最近刚赶上双 11,小区便利店的老王头也推出了一项「空酒瓶子换酒」的促销活动,它的规则是这样的。

本文已收录至 Github《小白学算法》系列:https://github.com/vipstone/algorithm

活动规则

客户购买 X 瓶酒,就可以用 Y 个空酒瓶来兑换一瓶新酒。

提示:

X 和 Y 的取值如下:

  • 1 <= X <= 100

  • 2 <= Y <= 100

Y 值不固定,随机抽取。

如果喝掉了酒瓶中的酒,那么酒瓶就会变成空的。

请你计算最多能喝到多少瓶酒

示例 1:

输入:X = 9, Y = 3

输出:13

解释:你可以用 3 个空酒瓶兑换 1 瓶酒。所以最多能喝到 9 + 3 + 1 = 13 瓶酒。

示例 2:

输入:X = 15, Y = 4

输出:19

解释:你可以用 4 个空酒瓶兑换 1 瓶酒。所以最多能喝到 15 + 3 + 1 = 19 瓶酒。

示例 3:

输入:X = 5, Y = 5

输出:6

示例 4:

输入:X = 2, Y = 3

输出:2

解题思路

这道题难点有两个:第一,用多少个空瓶换一瓶酒是不固定的(随机的);第二,兑换的酒喝完之后还能继续参与兑换活动。因此要在满足这两个的前提条件下,计算自己最多能喝到几瓶。

可能有些朋友看到了本篇标题之后就知道了解题思路,没错,我们本文就是要用「贪心算法」来计算最终答案。同时这道题也符合贪心算法的解题思路,那就是有酒瓶就兑换、能兑换多少就兑换多少。

贪心算法

贪心算法(Greedy Algorithm),又称贪婪算法,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。

贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。

贪心算法的实现框架

从问题的初始解出发:

while(能朝给定总目标前进一步)

{

    利用可行的决策,求出一个可行解元素;

}

由所有解元素组合成问题的一个可行解。

注意:因为用贪心算法只能通过解局部最优解的策略来达到全局最优解,因此,一定要注意判断问题是否适合采用贪心算法策略,找到的解是否一定是问题的最优解。

接下来我们就用代码来演示一下贪心算法的具体实现。

代码实现 1:贪心

首先我们先把全局问题转换成局部问题:当空瓶子能换一瓶酒的时候,我们就换一瓶酒,实现代码如下:

// 贪心1:用 + 和 - 实现
class Solution {public int numWaterBottles(int numBottles, int numExchange) {// 最大酒瓶数int total = numBottles;// 有酒瓶就兑换while (numBottles >= numExchange) {// 执行一轮兑换numBottles -= numExchange;++total;// 兑换一次多一个酒瓶++numBottles;}return total;}
}

代码解析

实现思路:

  1. 先把所有酒喝掉 int total = numBottles

  2. 有足够的空瓶就去换一瓶酒,执行一次 while 循环;

  3. 在循环中,空瓶的数量 +1,能喝到酒的数量 +1;

  4. 执行下一次循环判断。

我们将以上代码提交至 LeetCode,执行结果如下:

代码实现 2:贪心改进

以上的贪心算法是一瓶酒一瓶酒进行循环兑换的,那我们可否每次将所有的空瓶子全部兑换完(可兑换的最大值),然后将兑换的酒再喝完,再进行下一次兑换?

答案是肯定的,我们只需要使用取模和取余操作就可以实现了,具体代码如下:

// 贪心 2:用 / 和 % 实现
class Solution {public int numWaterBottles(int numBottles, int numExchange) {// 总酒瓶数int total = numBottles;// 有酒瓶就兑换while (numBottles >= numExchange) {// 最多可兑换的新酒int n = numBottles / numExchange;// 累计酒瓶total += n;// 剩余酒瓶(剩余未兑换 + 已兑换喝掉的)numBottles = numBottles % numExchange + n;}return total;}
}

我们将以上代码提交至 LeetCode,执行结果如下:

总结

贪心算法初看感觉很“难”,但具体实现起来却发现很简单。其实「算法」也是一样的,初看这个词感觉很难很高大上,其实它就是解决某个问题的一种思想、一种固定的“套路”而已,也并无神秘可言。

人常说:路虽远行则将至,事虽然难做者必成。“难”和“易”从来都是相对的,其实从“难”到“易”就是一个逐渐开悟、逐渐成长的过程。

愿你每天成长一点,最后留一个我的私人微信:GG_Stone,相互交流、共同进步。

参考 & 鸣谢

https://leetcode-cn.com/problems/water-bottles/

https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741375.html

https://zh.wikipedia.org/zh-hans/贪心算法


往期推荐

嗯,查询滑动窗口最大值的这4种方法不错....


小白学算法:买卖股票的最佳时机!


23张图!万字详解「链表」,从小白到大佬!


关注我,每天陪你进步一点点!

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

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

相关文章

java保留两位小数4种方法

转自&#xff1a; http://blog.csdn.net/ming1683/article/details/31950584种方法&#xff0c;都是四舍五入&#xff0c;例&#xff1a;import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; public class format {double f 111231…

AndroidStudio使用入门

AndroidStudio使用入门1_AndroidStudio activity的基本使用1.1_MainActivity和activity_main的初识1.2_Activity的清单文件简介1.3_几种重要文件的介绍1.4_基本布局的认识与使用1.4.1_RelativeLayout(相对布局)1.4.2_线性布局2_访问资源的方式2.1_java访问资源的方式2.2_xml访问…

java计算时间差距_硬计算和软计算之间的差异

java计算时间差距什么是计算&#xff1f; (What is Computing?) The process of accomplishing a particular task with the help of a computer or a computing device is known as computing. It should provide precise and accurate solutions, also it makes easy to fin…

主键字母自动生成函数

-- 动态生成字母方式主键&#xff0c;A-Z 大于Z自动进位【26进制数值表示】-- 参数&#xff1a;动态查询表和主键列 create or replace function charkey (tabName char, pkName char) return char asv_key varchar2(4); -- 表中查询出当前主键列最大值v_char varchar2(…

26.颜色值缩写

关于颜色的css样式也是可以缩写的&#xff0c;当你设置的颜色是16进制的色彩值时&#xff0c;如果每两位的值相同&#xff0c;可以缩写一半。 例子1&#xff1a; p{color:#000000;} 可以缩写为&#xff1a; p{color: #000;} 例子2&#xff1a; p{color: #336699;} 可以缩写为&a…

面试官:你说说互斥锁、自旋锁、读写锁、悲观锁、乐观锁的应用场景?

前言生活中用到的锁&#xff0c;用途都比较简单粗暴&#xff0c;上锁基本是为了防止外人进来、电动车被偷等等。但生活中也不是没有 BUG 的&#xff0c;比如加锁的电动车在「广西 - 窃格瓦拉」面前&#xff0c;锁就是形同虚设&#xff0c;只要他愿意&#xff0c;他就可以轻轻松…

计算机操作系统原理教程与实训(目录)

计算机操作系统原理教程与实训 第一章 计算机操作系统概论 1.1 操作系统的形成与发展 1.1.1 人工操作方式 1.1.2 脱机输入/输出技术 1.1.3 批处理技术 1.1.4 多道程序设计技术 1.2 操作系统的基本概念 1.2.1 操作系统的定义 1.2.2 操作系统的地位 1.2.3 操作系统的特征 1.2…

2万字,看完这篇才敢说自己真的懂线程池!

前言 线程池可以说是 Java 进阶必备的知识点了&#xff0c;也是面试中必备的考点&#xff0c;可能不少人看了一些文章后能对线程池工作原理说上一二&#xff0c;但这还远远不够&#xff0c;如果碰到比较有经验的面试官再继续追问&#xff0c;很可能会被吊打&#xff0c;考虑如下…

西南大学校园GIS平台

原文:西南大学校园GIS平台系统架构是B/S,开发语言是C#、silverlight&#xff0c;开发平台是.NET&#xff0c;数据库为sqlserver&#xff0c;这是我读研究生时候自己做的作品&#xff0c;以自己的母校为地图&#xff0c;进行GIS相关的功能分析&#xff0c;核心的模块有&#xff…

Android studio小问题解决

1_代码识别不出来问题 2_项目SDK与本地不匹配 先查看项目的SDK 增加本地SDK

使用类的银行管理系统的C ++程序

In this program, we are using the concept of C class and object, following basic operations are being performed here, 在此程序中&#xff0c;我们使用C 类和对象的概念&#xff0c;在此执行以下基本操作&#xff0c; Opening an account 开户 Show account info 显示…

2万字长文包教包会 JVM 内存结构

点击蓝色“Java中文社群”关注我哟加个“星标”&#xff0c;一起成长&#xff0c;做牛逼闪闪的技术人JVM ≠ Japanese Videos Man写这篇的主要原因呢&#xff0c;就是为了能在简历上写个“熟悉JVM底层结构”&#xff0c;另一个原因就是能让读我文章的大家也写上这句话&#xf…

vb.net 读写文件

读取和写入文件 以下示例将一行文本写入文件。 Write text to a file Sub WriteTextToFile() Dim file As New System.IO.StreamWriter("c:test.txt") file.WriteLine("Here is the first line.") file.Close() End Sub 以下示例将文件中的文本读取到…

Oracle 10g、11g :RAC关闭、启动、重启步骤

关闭顺序&#xff1a;【其他节点】-> [第一个节点]操作&#xff1a;step 1&#xff1a;{以grid用户或关闭监听&#xff1a; { crs_stop 监听器资源名 | srvctl stop listener } --全局|oracle用户关闭监听&#xff1a;{ lsnrctl stop } --单个节点}step 2&#xff1a;以orac…

虹软安卓人脸识别初学

1_下载SDK 进入虹软官网&#xff1a; 点击人脸识别SDK 进入开发者中心&#xff08;注册登录&#xff09; 新建应用并添加SDK 输入相应信息&#xff0c;确认 下载sdk 2_run示例代码注意事项 跑不起来的解决方法&#xff08;SDK版本不一致&#xff09; 3_激活并使用

css圆在中心根据宽度缩放_根据CSS中的容器宽度重新缩放字体

css圆在中心根据宽度缩放Introduction: 介绍&#xff1a; Dealing with fonts is a very interesting thing to do as fonts bring out the appearance of your website or a web page so you must choose the ideal fonts for your website or web page that helps in making…

vb.net 的 openFileDialog 控件文件筛选器使用

Filter 属性设置当前文件名筛选字符串&#xff0c;该字符串确定出现在对话框的“文件类型”框中的选项。 openFileDialog1.InitialDirectory "c:\\" ; openFileDialog1.Filter "txt files (*.txt)|*.txt|All files (*.*)|*.*" ; openFileDialog1.Filter…

Java中不可或缺的59个小技巧,贼好用!

来源&#xff1a;https://blog.dogchao.cn/?p70《Effective JavaJava》名著&#xff0c;必读。如果能严格遵从本文的原则&#xff0c;以编写API的质量来苛求自己的代码&#xff0c;会大大提升编码素质。以下内容只记录了我自己整理的东西&#xff0c;还是建议读原文。为了聚焦…

c# contains_清单 .Contains()方法,以C#为例

c# containsC&#xff03;List <T> .Contains()方法 (C# List<T>.Contains() Method) List<T>.Contains() method is used to check whether list contains a specified element or not. List <T> .Contains()方法用于检查list是否包含指定的元素。 S…

第一次使用Sourcetree成功上传gitee记录

第一次使用Sourcetree成功上传gitee记录2_克隆gitee仓库到本地1_设置密钥公钥3_上传本地工作区进而上传到gitee4_最后一步&#xff0c;将文件从本地master提交到gitee5_小问题汇总5.1_git远端打不开5.2_当有多个仓库在使用时设置多个密钥公钥5.3_账户公钥和仓库公钥使用ssh密钥…