无后效性问题:
- 不管通过什么方式到达某个状态,其返回值都一样。
1. 换钱的方法数
暴力递归
- 以arr = [5, 10, 25, 1],aim = 15为例:
节点中的内容表示:
- 从下标为[i~j]的数组中取任意张,可以换到aim的方法数
class Solution{
public:
int coins(int *arr, int len, int aim)
{
if (!arr || len == 0 || aim < 0)
return 0;
return help(arr, len, 0, aim);
}
private:
//从下标为[index~len-1]的数组中取任意张,可以换到aim的方法数
int help(int *arr, int len, int index, int aim)
{
int ret = 0;
if (index == len)
ret = (aim == 0) ? 1 : 0;
else{
for (int i = 0; arr[index] * i <= aim; i++)
{
ret += help(arr, len, index + 1, aim - arr[index] * i);
}
}
return ret;
}
};
可以发现 暴力递归 有许多重复性计算,可以使用记忆化搜索
class Solution{
public:
int coins(int *arr, int len, int aim)
{
if (!arr || len == 0 || aim < 0)
return 0;
memo = vector<vector<int>>(len + 1, vector<int>(aim + 1, -1));