硬币(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

解题思路

首先根据题目的意思,这明显是一个完全背包问题,只不过不同以往,这里要求求取可实现的方法次数,所以背包方式的求解就不再说,今天带来一种数学思维的求解方式,就算你没有学过算法【动态规划】,也应该能做出这道题。

1、根据题意,我们可以得出这样的公式(a枚25分的硬币,b枚10分硬币、c枚5分硬币、d枚1分硬币),根据它给出的硬币种类,所以不管给出多少分的数,都能被这四种硬币所组成(降低了难度)。
          25a + 10b + 5c + d =n;

2、根据所列式子,我们可以得出如果我们取出 i 枚25分硬币,剩下的数量就留给了10 、5 、1 分的硬币去构成,假设当25分硬币数为 a时,【result1 = n - 25a 】,所以I的取值为【0,n/25】;.

3、b、c、d又可以继续按照第二步骤的方法继续进行分,那么【ressult2 = result1-10b】,因此b的取值为【0,result1/10】;

4、因此c的取值为【0,result2/5】;因为【ressult2 = result1-10b】,则c的取值为【0,result1/5-2b】;

5、当a,b,c定了,d的值也就自然定下来了。因此,所有的表示种类,即为 a、b、c可取值数的组合。

6、b、c、d的不同表示种类有:
在这里插入图片描述
7、可能你会很奇怪的问:“为啥要 +1 啊?”,那我问你,它的零不是一种情况吗?对吧。所以相对于b、c、d的取值情况,可获取如下式子:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020042314042651.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzQ1MjQyNA==,size_16,color_FFFFFF,t_70
8、解决了b、c、d的取值,之后便处理a的情况:
在这里插入图片描述

代码

class Solution {
public:
    int waysToChange(int n) {
         const int mod  = 1000000007; 
        int res = 0;
        for (int i = 0; i <= n / 25; i ++) {
            int result = n - i * 25;
            int a = result / 5;
            int b = result / 10;
            res += (long long)(a + 1)*(b + 1) % mod - (long long)b*(b + 1)% mod;
            res %= mod;
        }
        return res;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值