什么是动态规划
动态规划是一种通过“大而化小”的思路解决问题的算法。区别于一些固定形式的算法,如二分法,宽度优先搜索法,动态规划没有实际的步骤来规定第一步做什么第二步做什么。
所以更加确切的说,动态规划是一种解决问题的思想。这种思想的本质是,将一个规模比较大的问题,通过规模比较小的若干问题的结果来得到的。
从另一方面来说,计算机是很笨的,我们最开始都是通过穷举法来解决问题,但随着数据量的增大,特别是信息爆炸的今天,如果一个页面不能很快速地给用户加载出来,那么用户很有可能会选择放弃打开这个页面。而穷举法消耗的算力、时间其实已经不能满足我们的需求了,因此,我们需要更高效的算法来解决问题。
但是穷举法应该算是思路最简单的方法了,可以说是基础中的基础,因此,在学习动态规划前,我们应该好好掌握这一方法。
下面,我们通过硬币找零问题来认识一下贪心算法。
硬币找零问题
移动支付已经成为了我们日常生活当中的主流支付方式,无论是在便利店购买一瓶水,还是在超市或菜市场购买瓜果蔬菜等生活用品,无处不在的二维码让我们的支付操作变得异常便捷。
但在移动支付成为主流支付方式之前,我们常常需要面对一个简单问题,就是找零的问题。
虽然说硬币找零在日常生活中越来越少,但它仍然活跃在编程领域和面试问题当中,主要还是因为它极具代表性,也能多方面考察一个开发人员或面试者解决问题的能力。下面来看看这个算法问题的具体描述。
问题描述
给定 n 种不同面值的硬币,分别记为 c[0], c[1], c[2], … c[n],同时还有一个总金额 k,编写一个函数计算出最少需要几枚硬币凑出这个金额 k?
每种硬币的个数不限,且如果没有任何一种硬币组合能组成总金额时,返回 -1。
示例
示例 1:
输入:c[0]=1, c[1]=2, c[2]=5, k=12
输出:3
解释:12 = 5 + 5 + 2
示例 2:
输入:c[0]=5, k=7
输出:-1
解释:只有一种面值为5的硬币,怎么都无法凑出总价值为7的零钱。
题目分析
首先,题目有两个个关键点:
- 第一个关键点是每种硬币的个数不限,这就意味着我们可以重复使用每一种硬币
- 第二个关键点是最少,如果没有最少这个字眼,那么这道题可能就会有很多答案
举个简单的例子,按照示例 1 的题设,有三种不同面值的硬币,分别为 c 0 = 1 c_0=1 c0=