1 solutions
-
0
Guest MOD
-
0
标准的深度优先搜索+回溯 问题建模
将问题转化为经典的“排列问题”,即从每本书中选择一个未被分配且被当前人喜欢的书,逐步构建完整的分配方案。
DFS递归框架
递归层级:每个层级对应一个人(例如第1层处理第1个人)。
选择范围:遍历所有书,跳过已被分配的或不被当前人喜欢的。
状态标记:用vis数组记录哪些书已被分配,避免重复使用。
回溯恢复:每次递归返回后,需要撤销当前选择,尝试其他可能性。
字典序保证
由于遍历书的顺序总是从1到m,且每次优先选择较小的书号,最终方案会自然按字典序生成,无需额外排序。
#include <bits/stdc++.h> using namespace std; int a[15][15]; // 存储喜好矩阵(a[i][j]=1表示第i个人喜欢第j本书) int n, m; // 人数n,书数m vector<int> tem; // 临时存储当前分配方案 vector<vector<int>> ans; // 存储所有合法方案 int vis[70]; // 标记书是否被分配(vis[j]=1表示书j已被分配) void dfs(int x) { // x表示当前处理到第几个人 if (x == n + 1) { // 递归终止条件:所有人处理完毕 ans.push_back(tem); return; } for (int i = 1; i <= m; i++) { // 遍历所有书 if (vis[i] || a[x][i] == 0) continue; // 跳过已被分配或不喜欢的书 vis[i] = 1; // 标记书i为已分配 tem.push_back(i); // 当前人选书i dfs(x + 1); // 递归处理下一个人 vis[i] = 0; // 回溯:撤销分配 tem.pop_back(); // 回溯:移除当前选择 } } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> a[i][j]; dfs(1); // 从第1个人开始递归 // 输出所有方案(已按字典序排列) for (auto &vec : ans) { for (int j : vec) cout << j << " "; cout << endl; } }
- 1
Information
- ID
- 1452
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 120
- Accepted
- 27
- Uploaded By