leetcode每日一题:硬币
题目描述
硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)
示例1:
输入: n = 5
输出:2
解释: 有两种方式可以凑成总金额:
5=5
5=1+1+1+1+1
示例2:
输入: n = 10
输出:4
解释: 有四种方式可以凑成总金额:
10=10
10=5+5
10=5+1+1+1+1+1
10=1+1+1+1+1+1+1+1+1+1
说明:
注意:
你可以假设:
0 <= n (总金额) <= 1000000
以下解题思路来自leetcode官方题解:https://leetcode-cn.com/problems/coin-lcci/solution/ying-bi-by-leetcode-solution/
解题思路
动态规划
用一个函数 f ( i , v ) f(i,v) f(i,v)表示前 i i i种硬币总和为 v v v的方案数, c i c_i ci表示第 i i i种硬币的面值。例如用可用硬币有 { 1 , 5 , 10 , 25 } \{1, 5, 10, 25\} { 1,5,10,25},要凑成90分,那么此处 i = 4 i=4 i=4, v = 90 v=90 v=90, c 4 = 10 c_4 = 10 c4=10。函数 f ( i , v ) f(i,v) f(i,v)可以写成 f ( 4 , 90 ) f(4,90) f(4,90)。
那么如果我们想凑成90分,可以考虑成这样一个问题,25分的硬币取0个,1个,2个或者3个(4个25分的就是100了)。然后再从25分的硬币可取的4种情况下分别讨论其他硬币的方案,有4种:
f ( 3 , 90 ) f ( 3 , 90 − 1 × 25 ) , f ( 3 , 90 − 2 × 25 ) , f ( 3 , 90 − 3 × 25 ) f(3,90)\quad f(3,90- 1×25),\quad f(3,90-2×25),\quad f(3,90-3×25) f(3,90)f(3,90−1×25),f(3,90−2×25),f(3,90−3×25)
那么
f ( 4 , 90 ) = f ( 3 , 90 ) + f ( 3 , 90 − 1 × 25 ) + f ( 3 , 90 − 2 × 25 ) + f ( 3 , 90 − 3 × 25 ) f(4,90) =f(3,90)+ f(3,90- 1×25)+ f(3,90-2×25)+f(3,90-3×25) f(4,90)=f(3,90)+f(3,90−1×25)+f(3,90−2×25)+f(3,90−3×25)
把上式抽象为一般情况,为
f ( i , v ) = ∑ j = 0 k f ( i − 1 , v − j × c i ) , k = ⌊ v c i