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];
    }

 

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