美文网首页
每日leetcode 面试题 08.11 2020-03-19

每日leetcode 面试题 08.11 2020-03-19

作者: 五道口的程序狐 | 来源:发表于2020-04-23 11:42 被阅读0次

面试题 08.11. 硬币

硬币。给定数量不限的硬币,币值为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

解法

这个和官方题解里面的方法一类似,但是有一点差别。

官方题解里面,最后得到的是:

f(i,v)=f(i−1,v)+f(i,v−c_i​)

举例来说,如果我想要用4种硬币(分别是1、5、10、25)来凑成100分,那我可以先算出来用3种硬币(1、5、10)凑成100分的方法,再算出来用4种硬币(1、5、10、25)凑成75分的方法数,把他们加起来。

这样的好处是,我们可以只用前面i-1的数据算出来i的数据,就不用存所有行了。

我这里的解法稍微差一些,是记录了四个数组,分别表示:最大用了1分、最大用了5分、最大用了10分、最大用了25分的前提下的种类数。

如果我想要用4种硬币(分别是1、5、10、25)来凑成100分,那我可以先算出来:

  • 用最大为25的硬币(也就是说,用了4种硬币(1、5、10、25)并且必须有25)凑成75分的方法;
  • 用最大为10的硬币(也就是说,用了3种硬币(1、5、10)并且必须有10)凑成75分的方法;
  • 用最大为5的硬币(也就是说,用了2种硬币(1、5)并且必须有5)凑成75分的方法;
  • 用最大为1的硬币(也就是说,用了1种硬币(1)并且必须有1)凑成75分的方法。

最后加起来就是总的方法数。

不如csx大佬的官方题解,但是也是正确的做法。

class Solution {
public:
    int waysToChange(int n) {
        if (n == 0) {
            return 1;
        }
        vector<int> dp_max_1(n + 1, 1);
        vector<int> dp_max_5(n + 1, 0);  // 必须有至少一个5
        vector<int> dp_max_10(n + 1, 0);
        vector<int> dp_max_25(n + 1, 0);
        for (int i = 5; i <= n; i++) {
            dp_max_5[i] = (dp_max_1[i - 5] + dp_max_5[i - 5]) % 1000000007;  // use one 5, will get dp_max_1[i - 5]; use two 5s, dp_max_5[i - 5]
        }
        for (int i = 10; i <= n; i++) {
            dp_max_10[i] = (dp_max_1[i - 10] + dp_max_5[i - 10] + dp_max_10[i - 10]) % 1000000007;
        }
        for (int i = 25; i <= n; i++) {
            dp_max_25[i] = (dp_max_1[i - 25] + dp_max_5[i - 25] + dp_max_10[i - 25] + dp_max_25[i - 25]) % 1000000007;
        }
        return (dp_max_1[n] + dp_max_5[n] + dp_max_10[n] + dp_max_25[n]) % 1000000007;
    }
};

相关文章

网友评论

      本文标题:每日leetcode 面试题 08.11 2020-03-19

      本文链接:https://www.haomeiwen.com/subject/eupoihtx.html