美團筆試題(一)-[程式設計題] 拼湊錢幣
[程式設計題] 拼湊錢幣
給你六種面額 1、5、10、20、50、100 元的紙幣,假設每種幣值的數量都足夠多,編寫程式求組成N元(N為0~10000的非負整數)的不同組合的個數。
輸入描述:
輸入包括一個整數n(1 ≤ n ≤ 10000)
輸出描述:
輸出一個整數,表示不同的組合方案數
輸入例子1:
1
輸出例子1:
1
分析:其中假設所有的錢幣總數為
。總共有
種錢幣。我們用
當我們只使用1種硬幣的時候,所有的組合情況如下:
使用硬幣數 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|
只使用1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
1和5 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 3 | 3 |
1、5和10 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 4 | 4 |
依次往下。
當我們增加一種硬幣(硬幣5)的時候,組合的結果相對於只使用1來說是,在原有隻有1的統計基礎上行,增加 1 個5元硬幣輸出的組合情況 + 增加2個5元硬幣輸出得組合情況 + … + 直到增加到最大的 5 元硬幣數量為止。就如具體的取 來說明。
當我們新增加一個5元硬幣時,使用硬幣5的所有次數取值範圍為 。其中 。
我們分情況來考慮:
- 當使用0個5元時,就是上面用1組成數字n的情況;
- 當時用1個5元時,就是上面用1組成數字n-5的情況;
- 當使用2個5元時,就是上面用1組成數字n-2*5的情況。
所以,當使用1和5兩種硬幣表示數字n=10的時候,就是講上面的所有情況累加 。總結成通用的公式就如下所示
程式碼實現如下:
public class Solution {
static int[] values = {1,5,10,20,50,100};
static int combine(int n) {
n++; // 主要是需要多增加一個為0的時候空位,不然會出錯
int[][] dp = new int[values.length][n];
for (int i = 0; i < n; i++) {
dp[0][i] = 1;
}
for (int i = 1; i < values.length; i++) {
for (int j = 0,k; j < n; j++) {
k = j/values[i];
while(k>=0){
dp[i][j] += dp[i-1][j-k*values[i]];
k--;
}
System.out.print(dp[i][j]+"\t");
}
System.out.println();
}
return dp[values.length-1][n-1];
}
public static void main(String[] args){
System.out.println(combine(20));
}
}