回溯法
http://en.wikipedia.org/wiki/Backtracking
回溯法:基于记忆。在某个点(回溯点),前进试探一种的方案,然后再回退到这个点,前进试探下一种方案。
- 其与递归,状态树的树枝扩展,深度优先有着某些本质联系。
- 需要显式或隐式的记忆:哪些被前进尝试过,哪些未被前进尝试过。
- 在回溯点回溯时需要:清理上一个方案的扩展状态,使用下一个方案的新扩展状态。
问题:给出一些数目,可以用加减乘除计算结果,求一些满足条件的结果。例如算24点。
简化:生成+-*/的所有可能计算方式。(貌似不是数学中的排列,也不是数学中的组合)
求解:(递归实现的)回溯法。
#include <iostream> using namespace std; // 0=>+, 1=>-, 2=>*, 3=>/ int op[100]; void output(int n) { for(int i = 0; i <= n-1; i++) { switch (op[i]) { case 0: cout << "+"; break; case 1: cout << "-"; break; case 2: cout << "*"; break; case 3: cout << "/"; break; default: cout << "error"; break; } } cout << endl; } int count = 0; void back_tracking(int i, int n) { if (i == n ) { output(n); count++; } else { for(int k = 0; k <= 3; k++) { op[i] = k; // 回溯点, 意味着:取消op[i]的上一个值,重新设置op[i]新值,然后前进。 back_tracking(i+1,n); // op[i] = -1; } } } int main() { back_tracking(0,6); cout << count << " solutions found!" << endl; return 0; }