LeetCode 面试题 08.11. 硬币

问题描述:硬币。给定数量不限的硬币,币值为25分、10分、5分和1分,编写代码计算n分有几种表示法。(结果可能会很大,你需要将结果模上1000000007)

你可以假设:

  • 0 <= n (总金额) <= 1000000

解题思路:

1.按25的硬币的数量来分类,使用0个,1个,2个...;
2.设每一类剩下的钱为n,且$n=p10+q,\quad 0\le q<10.$那么当$q \ge 5$时,该类的总方案数量为$p(p+1)+p+1$,当$q > 5$时,该类的总方案数量为$p(p+1)+2(p+1)$;
3.有一个问题就是$p(p+1)$的计算,因为$n\le 10^6$,所以$p\le10^5$,因此$p(p+1)$有可能会溢出。于是我另外写了一个计算$p(p+1)mod1000000007$的函数.
class Solution {
public:
    //因为n <= 1000000, 所以p <= 100000. 因此每次都可以加10000*p,这样就不会超过1000000007
    int times_p_p1(const int& p) {//用于计算p*(p+1)mod1000000007
        int res = 0;
        int p1 = (p + 1) / 10000;
        int q1 = (p + 1) % 10000;
        res = q1 * p;
        while (p1 > 0) {
            res += 10000 * p;
            p1--;
            if (res >= 1000000007) res -= 1000000007;
        }
        return res;
    }
    int ex25(const int& n) {//由10和5组成n有多少种可能
        int res = 0;
        int p = n / 10;
        int q = n % 10;
        res = times_p_p1(p);
        if (q >= 5) return res + 2 * (p + 1);
        else return res + p + 1;
    }
    int waysToChange(int n) {
        int res = 0;
        while (n >= 0) {
            res += ex25(n);
            res %= 1000000007;
            n -= 25;
        }
        return res;
    }
};

猜你喜欢

转载自www.cnblogs.com/airfy/p/12760239.html