vault backup: 2026-06-10 11:19:43

This commit is contained in:
2026-06-10 11:19:43 +08:00
parent 788576ec4b
commit b9bc08ab2f
6 changed files with 391 additions and 209 deletions
+85 -44
View File
@@ -78,17 +78,26 @@ flowchart TD
### 五、回溯法一般框架
```plaintext
void backtrack(int t) {
```cpp
#include <vector>
using namespace std;
// 回溯法框架
// t: 当前搜索深度(第几个决策)
// n: 问题规模(总共需要做的决策数)
// x: 当前解向量
void backtrack(int t, int n, vector<int>& x) {
if (t > n)
output(x); // 到达叶节点,输出解
else {
for (int i = f(n,t); i <= g(n,t); i++) {
x[t] = h(i); // 第t个位置尝试第i种选择
if (constraint(t) && bound(t))
backtrack(t+1); // 满足约束,继续深入
// 否则剪枝,回退(x[t]会被下次循环覆盖)
}
// output(x); // 到达叶节点,输出解
return;
// f(n,t) 和 g(n,t) 为第t个位置可选值的范围
// h(i) 将第i个候选值赋给x[t]
// constraint(t) 为约束函数,bound(t) 为限界函数
for (int i = 1; i <= n; i++) {
x[t] = i; // 第t个位置尝试第i种选择
if (/* constraint(t) && */ /* bound(t) */ true)
backtrack(t + 1, n, x); // 满足约束,继续深入
// 否则剪枝,回退(x[t]会被下次循环覆盖)
}
}
```
@@ -116,23 +125,40 @@ void backtrack(int t) {
**时间复杂度**:最坏 O(mⁿ),四色问题为 O(4ⁿ)
```plaintext
function graphColoring(graph, m, colors, vertex):
if vertex == n:
printSolution(colors) // 所有顶点着色完成
return
```cpp
#include <vector>
#include <iostream>
using namespace std;
for c = 1 to m:
colors[vertex] = c // 尝试颜色c
if isSafe(graph, colors, vertex):
graphColoring(graph, m, colors, vertex + 1)
colors[vertex] = 0 // 回溯
// 判断将 vertex 着色为 colors[vertex] 是否安全
bool isSafe(vector<vector<int>>& graph, vector<int>& colors, int vertex) {
int n = graph.size();
for (int v = 0; v < n; v++) {
if (graph[vertex][v] && colors[v] == colors[vertex])
return false; // 相邻顶点颜色相同,不安全
}
return true;
}
function isSafe(graph, colors, vertex):
for each neighbor v of vertex:
if colors[v] == colors[vertex]:
return false
return true
// 图着色回溯算法
// graph: 邻接矩阵, m: 颜色数, colors: 着色方案, vertex: 当前处理的顶点
void graphColoring(vector<vector<int>>& graph, int m, vector<int>& colors, int vertex) {
int n = graph.size();
if (vertex == n) {
// 所有顶点着色完成,输出解
for (int i = 0; i < n; i++)
cout << colors[i] << " ";
cout << endl;
return;
}
for (int c = 1; c <= m; c++) {
colors[vertex] = c; // 尝试颜色c
if (isSafe(graph, colors, vertex))
graphColoring(graph, m, colors, vertex + 1);
colors[vertex] = 0; // 回溯
}
}
```
```mermaid
@@ -173,29 +199,44 @@ flowchart TD
- 检查列冲突和对角线冲突
- 冲突则剪枝
```plaintext
function solveNQueens(board, row, n):
if row == n:
printBoard(board)
return
```cpp
#include <vector>
#include <iostream>
using namespace std;
for col = 0 to n-1:
if isSafe(board, row, col, n):
board[row][col] = "Q" // 放置皇后
solveNQueens(board, row + 1, n)
board[row][col] = "." // 回溯
function isSafe(board, row, col, n):
// 判断在 (row, col) 放置皇后是否安全
bool isSafe(vector<string>& board, int row, int col, int n) {
// 检查同一列
for i = 0 to row-1:
if board[i][col] == "Q": return false
for (int i = 0; i < row; i++)
if (board[i][col] == 'Q') return false;
// 检查左上对角线
for i = row-1, j = col-1; i >= 0 && j >= 0; i--, j--:
if board[i][j] == "Q": return false
for (int i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--)
if (board[i][j] == 'Q') return false;
// 检查右上对角线
for i = row-1, j = col+1; i >= 0 && j < n; i--, j++:
if board[i][j] == "Q": return false
return true
for (int i = row - 1, j = col + 1; i >= 0 && j < n; i--, j++)
if (board[i][j] == 'Q') return false;
return true;
}
// N皇后回溯算法
// board: 棋盘, row: 当前处理的行, n: 棋盘大小
void solveNQueens(vector<string>& board, int row, int n) {
if (row == n) {
// 输出一个解
for (int i = 0; i < n; i++)
cout << board[i] << endl;
cout << endl;
return;
}
for (int col = 0; col < n; col++) {
if (isSafe(board, row, col, n)) {
board[row][col] = 'Q'; // 放置皇后
solveNQueens(board, row + 1, n);
board[row][col] = '.'; // 回溯
}
}
}
```
**解释**:N皇后是经典的回溯应用。由于每行只放一个皇后,解空间是排列树。剪枝函数检查列冲突和两条对角线冲突,大幅减少搜索空间。