Algorithm
This commit is contained in:
80
Algorithm/BackTracking/readme.md
Normal file
80
Algorithm/BackTracking/readme.md
Normal file
@@ -0,0 +1,80 @@
|
||||
回溯法(Backtracking)是一种**系统地枚举所有可能解**的方法,通常用于解决**组合、排列、约束满足等问题**。它的核心思想是:在搜索问题的解空间时,如果发现当前部分解无法得到最终解,就**立即放弃(回溯)**,避免无谓的计算。
|
||||
|
||||
我给你拆开讲:
|
||||
|
||||
---
|
||||
|
||||
### 1️⃣ 基本思路
|
||||
|
||||
1. 从问题的初始状态开始,尝试每一种可能的选择。
|
||||
2. 对于每一种选择:
|
||||
|
||||
* 判断是否符合条件(约束)。
|
||||
* 如果符合,就继续尝试下一步。
|
||||
* 如果不符合,直接放弃(剪枝)。
|
||||
3. 当到达最终状态时,把解记录下来。
|
||||
4. 搜索完当前选择后,撤销选择(回到上一步),尝试其他可能。
|
||||
|
||||
这个“尝试→失败→撤销→尝试其他”过程就是“回溯”。
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ 典型问题
|
||||
|
||||
回溯法适合解决这类问题:
|
||||
|
||||
* **排列问题**:生成1\~n的所有排列。
|
||||
* **组合问题**:从n个元素中选出k个组合。
|
||||
* **子集问题**:生成所有子集。
|
||||
* **棋盘类问题**:N皇后、数独、填字游戏。
|
||||
* **约束满足问题**:图着色、八数码问题等。
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ 模板代码(C++示例)
|
||||
|
||||
以**N皇后问题**为例:
|
||||
|
||||
```cpp
|
||||
vector<int> queens; // queens[i] = 列号
|
||||
int n;
|
||||
|
||||
bool isValid(int row, int col) {
|
||||
for(int i = 0; i < row; i++) {
|
||||
int c = queens[i];
|
||||
if(c == col || abs(c - col) == row - i)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void backtrack(int row) {
|
||||
if(row == n) {
|
||||
// 找到一个解
|
||||
for(int c : queens) cout << c << " ";
|
||||
cout << endl;
|
||||
return;
|
||||
}
|
||||
for(int col = 0; col < n; col++) {
|
||||
if(isValid(row, col)) {
|
||||
queens.push_back(col); // 选择
|
||||
backtrack(row + 1); // 递归
|
||||
queens.pop_back(); // 回溯
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ 总结
|
||||
|
||||
* 回溯法是一种**DFS+剪枝**的方法。
|
||||
* 核心是**选择、约束、递归、撤销**。
|
||||
* 常用于**枚举问题、组合问题和约束满足问题**。
|
||||
|
||||
---
|
||||
|
||||
如果你愿意,我可以给你画一张**回溯法搜索树的示意图**,直观理解它是怎么“尝试、失败、回退”的。
|
||||
|
||||
你想让我画吗?
|
Reference in New Issue
Block a user