程序员面试金典——9.8硬币表示

程序员面试金典——9.8硬币表示

参考网址:https://www.nowcoder.com/profile/1434243/codeBookDetail?submissionId=12603339
Solution1:
1.配套书上的递归解法
约定不同硬币凑成的值为n,硬币面值从小到大为[1,5,10,25]
这里逐步分析组成n的过程。
如果放秤砣一样,按照从大到小的顺序,考虑可能存在几个25 =>每种情况下存在几个10 =>每种情况下存在几个5 =>依此类推
程序员面试金典——9.8硬币表示_第1张图片

class Coins {
public:
    int countWays(int n) {
        // write code here
        int denom = 25;
        return fun(n, denom);
    }

    int fun(int n, int coin) {
        int nextcoin=0;
        switch(coin) {
            case 25:
                nextcoin=10; break;
            case 10:
                nextcoin=5; break;
            case 5:
                nextcoin=1; break;
            case 1:
                return 1;
        }

        int res=0;
        for(int i = 0; i * coin <= n; i++) {
            res += fun(n-i*coin, nextcoin)%1000000007;
        }
        return res%1000000007;//%1000000007
    }
};

n为100的时候正确输出242,但是题目数据量到了10w级别运行出现超时。
Solution2:
2.动态规划
我们用dp[i](i属于1~n ) 表示组合成i元一共有几种方法。

首先所有的硬币组合问题都要有基础面值:1元。i的总组合方法一定等于i中最后coin元不用新面值的方法+最后coin元使用新面值的方法。

而最后coin元 使用新面值的方法必然等于i-coin的总组合方法。
不用新面值的方法就是旧值

假如只有1元,那对于任给的1~n,必然只有1中组合方法。
假设增加一种新面值:coin元。对于任意i(i属于1~n),
当i < coin的时候,新面值组合方法为0,dp[i]不变。
当i = coin,新组合方法为1,总dp[i]=旧dp[i]+1
当coin < i < 2*coin,新组合方法仍然为1,总dp[i]=旧dp[i] + 新dp[i-coin]
当i=2coin,仍然有总 dp[i]=旧dp[i] + 新dp[i- coin]
以coin = 2为例
程序员面试金典——9.8硬币表示_第2张图片
同样的道理,题目coin值取值为:[1 5 10 25],迭代处理即可

class Coins {
public:
    int countWays(int n) {
        int coins[4]={1,5,10,25};
        int dp[100001]={0};       
        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];
    }   
};

你可能感兴趣的:(程序员面试金典题目笔记)