题目
给定一组面值纸币,比如[2,3,5,100],每张纸币可以使用任意次,给定金额1000,要求返回找余钱为0的方法数量
- 该题的遍历思路为假设选一张选2,那第二个3的最大取值范围就是997,如果选了2和3各一张,那第三个5的取值范围就算995,如果前三个都各取一张,最后一个100的取值范围就是990
- 所以每个纸币能使用的的数量是不超过留给它余额的/自身金额,比如选了2和3各一张,那5最多只能取17张
- 所以遍历模式为0位置能取的张数,1位置为0位置取的张数的余额能取到的张数
function process(arr, index, rest) {
// 已经越界的情况
if (index === arr.length) {
return rest === 0 ? 1 : 0;
}
let ways = 0;
// 因为每次i从0开始,所以就算rest为0也会一直进入到下一位直到越界
for (let i = 0; arr[index] * i <= rest; i++) {
ways += process(arr, index + 1, rest - arr[index] * i);
}
return ways;
}
// 这种终结方式和上面等效
function process2(arr, index, rest) {
if (index === arr.length) {
return rest === 0 ? 1 : 0;
}
if (rest === 0) {
return 1;
}
if (rest < 0) {
return 0;
}
let ways = 0;
for (let i = 0; arr[index] * i <= rest; i++) {
ways += process2(arr, index + 1, rest - arr[index] * i);
}
return ways;
}