How to avoid stack problems(记忆化出场)
1- If must do it in recursion, then avoid any unnecessary local data. Move to global as possible
2- Move to iterative procedure
3- Implement your own stack calls!
// Fibonacci Series: Fib(n) = fib(n-1) + fib(n-2). Fib(0) = fib(1) = 1
int fib(int n)
{
if(n <= 1)
return 1;
return fib(n-2) + fib(n-1);
}
// what is search space? n
// what is number of recursive calls? We are branching every time to 2 levels that differs in 1
// fib(5)
// fib(4) fib(3)
// fib(3) fib(2) fib(2) fib(1)
// fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)
// fib(1) fib(1)
//
// We almost have 2^N calls
// Wait, a space of N, is called 2^N times!
// A fib of 50 do around ~1125899906842624 call!!!!!!
//
// Then, we must call a state more than once? and it too call other states, that already called!
//
// Check tree above, fib(3) called twice. Fib(2) called three times!
//
// Let's SAVE the answer, and let space of N is called 2N times!
int savedAnswers[MAX]; /// Initialized to -1, means no answer
int fibSave(int n)
{
if(n <= 1)
return 1;
if(savedAnswers[n] != -1)
return savedAnswers[n];
return savedAnswers[n] = fib(n-2) + fib(n-1);
}
// fib(5)=8
// fib(4)=5 fib(3)=3
// fib(3)=3 fib(2)=2
// fib(2)=2 fib(1)=1
// fib(1)=1 fib(1)=1
memoization记忆化
记忆化搜索,是在学习动态规划的时候,用到的。用记忆化搜索的方式,实现dp。在这个章节,练习题目时,也请感受一下记忆化操作。
// 记忆化模板
int g[MAXN]; // 定义记忆化数组
int ans = 最坏情况, now;
void dfs f(传入数值) {
if (g[规模] != 无效数值) return; // 或记录解,视情况而定
if (到达目的地) ans = 从当前解与已有解中选最优; // 输出解,视情况而定
for (遍历所有可能性)
if (可行) {
进行操作;
dfs(缩小规模);
撤回操作;
}
}
int main() {
memset(g, 无效数值, sizeof(g)); // 初始化记忆化数组
}