丨硬币找零问题从贪心算法说起_第1页
丨硬币找零问题从贪心算法说起_第2页
丨硬币找零问题从贪心算法说起_第3页
丨硬币找零问题从贪心算法说起_第4页
丨硬币找零问题从贪心算法说起_第5页
已阅读5页,还剩12页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

你不妨带着这个问题来学习下面的内容移动支付已经成为了我们日常生活当中的主流支付方式,无论是在便利店一瓶,还是在超市或菜市场瓜果蔬菜等生活用品,无处不在的让我们的支付操作得异既然如此,我们就先来看看这个算法问题的具体描问题n同面值的硬币,分别记为c[0c[1c[2c[n],同时还有一个总k,编写一个函数计算出最少需要几枚硬币凑出这个金额k?每种硬币的个数不限,且如果没有任何一种硬币组合能组成总金额时,返回-1。代1代1234示例输入:c[0]=1,c[1]=2,c[2]=5,输出5解释:12=5+5+12345示例输入:c[0]=5,输出:-解释:只有一种面值为5的硬币,怎么都无法凑出总价值为7的零钱举个简单的例子,按照示例1的题设,有三种不同面值的硬币,分别为,c2,代代1解1:输出:5,因为5+2+2+2+1=122解2:输出:6,因为2+2+2+2+2+2=123解3:输出:12,因为1+1+1+1+1+1+1+1+1+1+1+1=12所以,这是一个求最值的问题。那么求最值的问题是什么呢?嗯,无非就是穷举,这种现象称之为子问题。在尝试解决硬币找零问题前,我们先用较为严谨的定义来回顾一下贪心算法的概整体最优解。因此,我们可以得到贪心算法的基根据问题来建立数学模型,一般面试题会定义一个简现在让我们回到这个问题上来既然这道题问的是最少需要几枚硬币凑出金额k,那么是否可以尝试使用贪心的思想来解这个想法不错,让我们一起来试一我用一个例子,带你看下整个贪心算法求解的过程,我们从c[0]=5,c[1]=3k=11情况下寻求最少硬币数。按照“贪心原则”,我们先挑选面值最大的,即为5的硬币放入钱包。接着,还有6待解(11-56)。这时,我们再次“贪心”,放入5面值的硬Java代代intintgetMinCoinCountHelper(inttotal,int[]values,int{intrest=intcount=//for(inti=0;i<valueCount;++i)intcurrentCountrestvalues[i];计算当前面值最多能用多少个rest-=currentCount*values[i];//计算使用完当前面值后的余额count+=currentCount;//增加当前面额用量if(rest=={return}return-1;//如果到这里说明无法凑出总价,返回-}intgetMinCoinCount()intvalues53inttotal=11;//returngetMinCoinCountHelper(total,values,2}C++123456789intGetMinCoinCountHelper(inttotal,int*values,intvalueCount){intrest=total;intcount=//从大到小遍历所有面for(inti=0;i<valueCount;++i)intcurrentCount=rest/values[i];//计算当前面值最多能用多少个rest-=currentCount*values[i];//计算使用完当前面值后的余额count+=currentCount;//增加当前面额用量if(rest==0){returncount;}}return-1;//如果到这里说明无法凑出总价,返回-}intGetMinCoinCount()intvalues[]={5,3};//硬币面inttotal=11;//总returnGetMinCoinCountHelper(total,values,2);//输出结2323嗯。。。你有没有发现问题?那就是还剩1零钱待找,但是我们只有c[0]=5,c[1]=3种面值的硬币,怎么办?这个问题无解了,该返回-1了吗?显然不是。我们把第2步放入的5元硬币取出,放入面值为3元的硬币试试看。这时,你就会发现,我们还剩3元零钱待找。正好我们还有c[1]=3硬币可以使用,因此解是c[0]=5,c[1]=3,c[1]=3,即最少使用三枚硬币凑出了k=11这个金额。Java代代intgetMinCoinCountOfValue(inttotal,int[]values,intvalueIndex)intvalueCount=if(valueIndex==valueCount){returnInteger.MAX_VALUE;45minResult=6currentValue=7maxCount=total/89(intcount=maxCount;count>=0;count--{intrest=total-count*//如果rest为0,表示余额已除尽,组合if(rest==0)minResult=Math.min(minResult,

//否则尝试用剩余面值求当前余额的硬币intrestCount=getMinCoinCountOfValue(rest,values,valueIndex+//如果后续没有可用组if(restCount==Integer.MAX_VALUE)//如果当前面值已经为0,返回-1表示尝试失if(count==0){break;否则尝试把当前面值-1}minResult=Math.min(minResult,count+33

returnintgetMinCoinCountLoop(inttotal,int[]values,intk)intminCount=intvalueCount=if(k==valueCount)returnMath.min(minCount,getMinCoinCountOfValue(total,values,}(inti=k;i<=valueCount-1;i++)//k位置已经排列intt=values[k]=minCount=Math.min(minCount,getMinCoinCountLoop(total,values,k+//回t=values[k]=}return}getMinCoinCountOfValue()int[]values={5,3//inttotal=11;//总intminCoin=getMinCoinCountLoop(total,values,return(minCoinInteger.MAX_VALUE1:minCoin;//}代intGetMinCoinCountOfValue(inttotal,int*values,intvalueIndex,int2345678932

if(valueIndex==valueCount){returnINT_MAX;intminResult=intcurrentValue=values[valueIndex];intmaxCount=total/currentValue;for(intcount=maxCount;count>=0;count--){intrest=total-count*currentValue;//如果rest为0,表示余额已除尽,组合if(rest==0)minResult=min(minResult,count);}//否则尝试用剩余面值求当前余额的硬币intrestCount=GetMinCoinCountOfValue(rest,values,valueIndex+1,//如果后续没有可用组if(restCount==INT_MAX)//如果当前面值已经为0,返回-1表示尝试失if(count==0){break;//否则尝试把当前面值-1}minResult=min(minResult,count+}returnintGetMinCoinCountLoop(inttotal,int*values,intvalueCount,intk)intminCount=(k==valueCount)returnmin(minCount,GetMinCoinCountOfValue(total,values,0,}(inti=k;i<=valueCount-1;i++)k位置已经排列intt=values[k]=minCount=min(minCount,GetMinCoinCountOfValue(total,values,0,minCount=min(minCount,GetMinCoinCountLoop(total,values,//回t=values[k]=}returnreturn}GetMinCoinCountOfValue()intvalues[]={5,3//inttotal=11;//总intminCoin=GetMinCoinCountLoop(total,values,2,return(minCoin==INT_MAX)?-1:}嗯,这样就没问题了,对硬币找零问题来说,我们得到了理想从上面这个例子我们可以看出,如果只是简单采用贪心的思路,那么到用完2个5元硬的时候我们就已经黔驴技穷了——因为剩下的1无论如何都没法用现在的硬币凑出来。这就是贪心算法所谓的局部最优硬币,因为这样数量肯定最小,但是有的时候我们就进入了死胡同,就好比上面这个例虽然纯粹的贪心算法作用有限,但是这种求解局部最优所谓的整体最优肯定是从很多个局部最优中选择出来的,因此所有最优化问题的基础都是贪心算法。是穷举。这是因为只要我们能够找到所有可能的答案,从中挑选出最优解就是算法问题的结果。在没有优化的情况下,穷举从来就不算是一个好方法。所以我带你使用了贪心算法来解题,它是一种使用局部最优思想解题的算法(问题一个解出步但是通过硬币找零问题,我们也发现了贪心算法本身的局限不能保证求得的最后解是不能用来求最大或最小解只能求满足某些约束条件的可行解我们往往需要使用回溯来优化贪心算法,否则就会导致算法失效。因此,在求解最值问题时,我们需要更好的方法来解。在后面课程讲到递归和穷举优化问题的时候,我会讲到解整体最优12人觉得很赞|提建议 科技所有 不 售卖。页面已增加防盗追踪,将依 上一 导读|动态规划问题纷繁复杂,如何系统学习和掌握它下一 02|递归:当贪心失效了怎么办精选留言AshinInfoprivatestaticvoidgetMinCoinCountOfValue()int[]values={5,展2 15比如[1,7,10]amount=14101111会比771 10这让到了ai中的 mentlearning。个人认为有些偏全局优化?就如展5作者回复:你好Java 5int[valuesnewint[]{5,3inttotal11valuesnewint[]{5,41}展 3JavaC++ 2#includeintGetMinCoinCountOfValueHelper(inttotal,int*values,intvalueIndex,int展1 2展1 2展1展11 11 1展1展展dp(n)=min(dp(n-c[i])+1)i>=0&&i<c.length-展

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论