找零钱是一个经典的动态规划问题。这种问题,我建议,首先学会暴力解法,然后从暴力解法中优化出动态规划的解法,这样,更能体会动态规划的魅力。
问题描述
有n种不同币值的硬币,硬币数量无限。给定一个数量T,求用给定硬币凑出T的方法数量。
举个例子:
假设币值是: {1,2,3}
给定的T值: 5
输出所有的组合数量: 5
为啥是5呢,因为有5种不同的组合可以得到数值5,如下所示:
{1,1,1,1,1}
{1,1,1,2}
{1,2,2}
{1,1,3}
{2,3}
暴力解法
既然这是要找所有的组合数量,暴力搜索就是很自然的想法了。暴力搜索算法写起来有两个关键点:
记下已经搜索到的结果,并且越简单越好,因为空间占用小啊。
记下剩余可用的搜索空间
简单说,就是我已经有了什么,我还可以有什么。
这两点,会因为具体问题不同而有不同的表现形式。
对这道凑币值的问题。我们的暴力搜索问题,可以看作是往一个布袋中放硬币,直到布袋中硬币的币值之和等于要求的数量。
看起来,布袋中的硬币就是我们已经搜索到的结果。剩余可选的硬币和还需要凑的币值就是我们可用的搜索空间。
这个虽然没有问题。但是我们需要一个数组来存储布袋中的硬币,这个空间开销还是不小。而且,这个问题并不要求我们给出具体的组合方案,而是只要所有可能的组合数量。鉴于此,我们可以做一个优化:将已经搜索到的结果用还需要凑的币值来表示显然&#x