Algorithm

This commit is contained in:
e2hang
2025-08-30 21:59:50 +08:00
parent 9077007670
commit daeec35f97
13 changed files with 453 additions and 0 deletions

View 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+剪枝**的方法。
* 核心是**选择、约束、递归、撤销**。
* 常用于**枚举问题、组合问题和约束满足问题**。
---
如果你愿意,我可以给你画一张**回溯法搜索树的示意图**,直观理解它是怎么“尝试、失败、回退”的。
你想让我画吗?