LeetCode 刷题系列- 面试题 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/coin-lcci

思路:将硬币排成一个序列:1、5、10 与 25

1 、得到状态转移方程

  利用前 i 种硬币来凑成钱数 v 的共有  f ( i , v ) 中方法,则  有递推公式  f ( i , v ) = f(i -1,v) + f( i-1 , v - ci) + f( i -1 , v - 2*ci) +  f( i -1 , v - 3*ci)  + ... +  f( i -1 , v - k*ci)   其中 k = [v / ci ] (k取不大于 v/ci 的最大整数),

 则有  f ( i , v  - ci ) = f(i -1,v - ci ) + f( i-1 , v - 2 * ci) + f( i -1 , v - 3*ci) +  f( i -1 , v - 4*ci)  + ... +  f( i -1 , v - k*ci) 

即   f ( i , v ) =  f(i -1,v)  + f ( i , v  - ci )   状态转移方程

2、利用状态转移方程

定义两个长度为 n + 1 的一维数组 d1[n+1]  与 d2[n+1] ,其中 d1数组保存的是 前 i-1种硬币凑成相应下标数目钱的方法数, d2数组保存的是 前 i 种硬币凑成相应下标数目钱的方法数,比如 d1[v]  = f ( i-1,v )   d2[v] = f ( i , v )  

首先初始化数组 d1 ,d1 所有元素初始化为 1 ,迭代数组 d1 与 d2

 nums = {1,5,10,25}   

 伪代码:

     d2[0] = 1

      for ( i=1;i<nums.length;i++){

        coin = nums[i]

      for(j = coin;j<=n;j++){

       d2[j] = d1[j] + d2[j - coin]     

}

 for(j = 0;j<=n;j++){

       d2[j] = d1 [j]  

}

  }

java 代码如下:

 public int waysToChange(int n) {
        int[]  coins = {1,5,10,25};
            int[]  d1 = new int[n+1];
            int[]  d2 = new int[n+1];
            d1[0] = 1;  //凑成钱数0 的方法只有 1 种
            d2[0] = 1;  //凑成钱数0 的方法只有 1 种
            //初始化,只能用一种硬币凑成第一种硬币的整数倍的钱数
            for(int j=coins[0];j<=n;j+=coins[0]){
                d1[j] = 1;
                if(j<coins[1]){
                    d2[j] = 1;    //在小于第二种硬币的钱数,方法数为1
                }
            }
        int mod = 1000000007;

        for(int i=1;i<coins.length;i++){
            int coin = coins[i];
            for(int j=coin;j<=n;j++){
                d2[j] = (d1[j] + d2[j-coin])%mod; //   f ( i , v ) =  f(i -1,v)  + f ( i , v  - ci )   状态转移方程
            }
            for(int j=coin;j<=n;j++){
                d1[j] = d2[j];   //本轮迭代的状态值保存到d1中
            }
        }

        return d2[n];
    }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章