题目:
给一个面额,如100分,以及denominations,如1分,5分,10分,25分(每个denomination可以取任意多个),求该面额用这些denomiations的表示方法的个数。
public class Solution {
int makeChange(int n) {
int[] denoms = {25, 10, 5, 1};
int[][] map = new int[n+1][denoms.length];
return makeChange(n, denoms, 0, map);
}
//递归。
int makeChange(int amount, int[] denoms, int index, int[][] map) {
if(map[amount][index] > 0) {
return map[amount][index];
}
if(index >= denoms.length - 1)
return 1;
int denomAmount = denoms[index];
int ways = 0;
for (int i = 0; i * denomAmount <= amount; i++) {
int amountRemaining = amount - i * denomAmount;
ways += makeChange(amountRemaining, denoms, index + 1, map);
}
map[amount][index] = ways;
return ways;
}
//循环,用二维数组避免重复
int makeChanges(int n) {
int[] denoms = {1, 5, 10, 25};
int[][] ways = new int[n+1][denoms.length];
for(int i = 0; i < n; i++) {
if(i == 0) {
for(int j = 0; j < denoms.length; j++)
if(i + denoms[j] <= n)
ways[i + denoms[j]][j]++;
}
else {
for(int j = 0; j < denoms.length; j++) {
if(ways[i][j] != 0) {
for(int k = j; k < denoms.length; k++) {
if(i + denoms[k] <= n) {
ways[i + denoms[k]][k] += ways[i][j];
}
}
}
}
}
}
int result = 0;
for(int i = 0; i < denoms.length; i++)
result += ways[n][i];
return result;
}
public static void main(String[] args) {
Solution s = new Solution();
System.out.println(s.makeChange(100));
System.out.println(s.makeChanges(100));
}
}