题目描述:
硬币。给定数量不限的硬币,币值为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
解题思路:
一下就能看出来是dp,要注意的是两层循环应该谁写外面。
最开始写的是 1~n的循环在外面,然后每一层循环里分别取不同的硬币来相加,但是这样有可能会重复,比如当n=6时,选硬币1 + dp[5] 和 选硬币5 + dp[1] 是包含重复结果的,因为dp[5]中已经包含了硬币5这一种情况。
解决方法就是在选硬币1时,不要去考虑更高面值的硬币,实际就是把两层循环换一下即可(妙啊)。
class Solution {
public:
int waysToChange(int n) {
int dp[1000001];//dp[i]表示当钱为i是的选择数
memset(dp,0,sizeof(dp));
int coins[4] = {1,5,10,25};
dp[0]=1;
for(int i=0;i<4;i++)
{
for(int j=coins[i];j<=n;j++)
{
dp[j] = (dp[j] + dp[j-coins[i]]) %1000000007 ;
}
}
return dp[n];
}
};