1. 程式人生 > >換零錢:有數量不限的硬幣,幣值為25分、10分、5分和1分,請編寫程式碼計算n分有幾種表示法。

換零錢:有數量不限的硬幣,幣值為25分、10分、5分和1分,請編寫程式碼計算n分有幾種表示法。

換零錢:

有數量不限的硬幣,幣值為25分、10分、5分和1分,請編寫程式碼計算n分有幾種表示法。

給定一個int n,請返回n分有幾種表示法。保證n小於等於100000,為了防止溢位,請將答案Mod 1000000007。

測試樣例

6

返回:2

動態規劃

dp[i][sum] 使用i 種硬幣組成sum有多少種方式。

設v1,v2,v3,v4 硬幣的面值

sum = v1*x1+ v2*x2 + v3*x3 + v4*k;                        dp[i][sum]

{x1,x2,x3,k}

{0…x1}

{0…x2}

{0…x3}

{0…k}

k<=sum/v4;

sum_0 =  v1*x1+ v2*x2 + v3*x3 + v4*(k);                                    dp[i-1][sum-v4*k]

sum_1 =  v1*x1+ v2*x2 + v3*x3 + v4*(k-1);                                 dp[i-1][sum-v4*(k-1)]

sum_2 =  v1*x1+ v2*x2 + v3*x3 + v4*(k-2);                                 dp[i-1][sum-v4*(k-2)]

.

.

.

.

.

sum_n =  v1*x1+ v2*x2 + v3*x3 + v4*(k-n);                                   dp[i-1][sum-v4*(k-n)]

.

.

.

sum_k =  v1*x1+ v2*x2 + v3*x3 +v4*(k-k);                                     dp[i-1][sum]

sum = sum_0+sum_1+sum_2+sum_3+……+sum_n+sum_k;

dp[i][sum]=dp[i-1][sum] + dp[i-1][sum-v4]+….dp[i-1][sum-v4*n] +dp[i-1][sum-v4*k];  k<=sum/v4;

dp[i][sum] 可以由前面的一行得出

程式碼:

二維陣列:

 public int countWays(int n) {

  int coin[] = new int[]{1,5,10,25};

        int dp[][] = new int[5][n+1];

        for (int i = 0; i <= 4; ++i)

           {

               dp[i][0] = 1;

           }

        for(int i=1;i<=4;++i){

        for(int j=1;j<=n;++j){

        for(int k=0;k<=j/coin[i-1];++k){

        dp[i][j]+=dp[i-1][j-k*coin[i-1]];

        }

        }

        }

        return dp[4][n];

優化為一維陣列:

dp[i][sum]=dp[i-1][sum] + dp[i-1][sum-v4]+….dp[i-1][sum-v4*n] +dp[i-1][sum-v4*k];  k<=sum/v4;

行:我們只需要上一行的資料

列:我們只需要當前sum之前的資料

一次可以使用一維陣列 逐行求解

      假設n=20

                             1 5 10 20

     0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

0   1 0 0 0 0 0 0 0 0 0 0  0  0  0  0  0  0  0  0  0  0

1   1 1 1 1 1 1 1 1 1 1 1  1  1  1  1  1  1  1  1  1  1

2   1 1 1 1 1 2 2 2 2 2 3  3  3  3  3  4  4  4  4  4  5

3   1 1 1 1 1 2 2 2 2 2 4  4  4  4  4  4  4  4  4  4  9

4   1 1 1 1 1 2 2 2 2 2 4  4  4  4  4  4  4  4  4  4  9

public int countWays(int n) {

          int[] coin = new int[]{1,5,10,25};  

        int[] dp = new int[n+1];  

        dp[0]=1;  

        for (int i = 0; i < coin.length; i++) {  

            for (int j = coin[i]; j <= n; j++) {  

                dp[j] =(dp[j]+dp[j-coin[i]])%1000000007;  

            }  

        }  

        return dp[n]; 

參考:http://www.cnblogs.com/python27/archive/2013/09/05/3303721.html

題目來源:http://www.nowcoder.com/practice/c0503ca0a12d4256af33fce2712d7b24?tpId=8&tqId=11041&rp=3&ru=/ta/cracking-the-coding-interview&qru=/ta/cracking-the-coding-interview/question-ranking