搜索枚举,就是用搜索代替枚举,可以使算法时间复杂度降低,也可以帮助解决很多枚举(暴力)的算法无法解决(或很慢才能解决)的问题。
基本搜索枚举
有如下方程:$$a_1 x_1 + a_2 x_2 + a_3 x_3 + cdots + a_n x_n = 0$$ ((2 le n le 10, 1 le a_i le 5, -2 le x_i le 2, x_i in mathbb{Z}))
求其解的总数。
int ans = 0;
void dfs(int dep, int sum) {
if(dep == n) {
if (sum == 0){
ans++;
}
return ;
}
for (int i = -2; i <= 2; i++) {
dfs(dep + 1, sum + a[dep] * i);
}
}
(搜索枚举解法)
排列数
题面链接: https://www.luogu.com.cn/problem/P1706 (洛谷)
#include <bits/stdc++.h>
using namespace std;
const int N = 20;
int n;
int per[N];
bool vis[N];
void dfs (int dep) {
if(dep==n) {
for(int i = 0;i<n;++i) {
cout<<setw(5)<<per[i]<<setw(5);
}
cout<<endl;
return;
}
for (int i = 1;i<=n;++i) {
if(vis[i]) {
continue;
}
vis[i] = 1;
per[dep] = i;
dfs(dep+1);
vis[i] = 0;
}
}
int main()
{
cin >> n;
dfs(0);
return 0;
}
组合数
题面链接: https://paste.ubuntu.com/p/T5fxWJPCVk/(云剪贴板)
#include <iostream>
using namespace std;
const int N = 15;
int n, k;
int comb[N];
void dfs(int x, int dep) {
if(dep == k) {
for (int i = 0; i < k; i++) {
cout << comb[i] ;
}
cout << endl;
return;
}
if(x == 0) {
return ;
}
comb[dep] = x;
dfs(x - 1, dep + 1);
dfs(x - 1, dep);
}
int main()
{
cin >> n >> k;
dfs(n, 0);
return 0;
}