穷举法,又称枚举法,是指从可能的解的集合中一一枚举各个元素,用给定的检验条件判定哪些是无用的,哪些是有用的。能使命题成立即为其解。
穷举法本质上属于搜索算法,但他与搜索有所不同,因为适用于枚举法求解的问题必须满足:可预先确定解的数量;预先确定解变量的取值范围。
穷举算法的关键,首先是确定循环的范围,其次是找出判断解的条件。将这两个关键点解决,穷举算法解题是轻而易举的。
搜索算法和穷举法类似,对于那些无法用循环写出的穷举算法,使用递归或队列来实现求解。搜索的过程构成了一颗搜索树,搜索实际上是对搜索树的遍历。
搜索的顺序分为两种:深度优先搜索(DFS)和广度优先搜索(BFS)。其中深度优先搜索是沿着搜索树的深度遍历树的节点,尽可能深地搜索树的分枝。DFS通常用递归的方法实现。
广度优先搜索每次搜索其可以扩展的每一个节点,当一层节点全部搜索完成后,再依次搜索第一个可扩展节点可以扩展的所有节点。
除了搜索的顺序之外,还有搜索的方法,一般分为盲目搜索和启发式搜索。
启发式搜索是在搜索过程中加入了与问题有关的启发式信息,用于指导搜索朝着最有希望的方向前进,扫除不必要的搜索过程,加速问题求解并得到最优解。
启发式搜索的常见算法有A*算法,模拟退火算法、遗传算法等,我们最常用的是A*算法。A*算法最经典案例是八数码问题,状态函数h设置为未到达目标位置的数字的个数。
递归dfs
n根木棍一共可以拼出多少个不同的三角形
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,l[15];
//因为三边总长度是确定的
//将三角形保存为第一边的长度的100倍+第二边的长度
bool h[10000];
//判断三条边是否能构成三角形
//三角形没有出现过,每条边的长度一定比0大,并且两边之和大于第三边
//记录下该三角形
bool is_triangle(int a,int b,int c){
return !h[a*100+b]&&a&&b&&c&&a+b>c&&a+c>b&&b+c>a&&(h[a*100+b]=true);
}
//枚举每根木棍放到三堆中的哪一堆中
//再去判断三边
int dfs(int index,int a,int b,int c){
if(index==n){
return a<b&&b<c&&is_triangle(a,b,c);
}
return dfs(index+1,a+l[index],b,c)+dfs(index+1,a,b+l[index],c)+dfs(index+1,a,b,c+l[index]);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&l[i]);
}
memset(h,0,sizeof(h));
printf("%d\n",dfs(0,0,0,0));
}
return 0;
}
dfs示例_凑表达式为0
#include <bits/stdc++.h>
using namespace std;
int n; // 保存读入的整数N
bool opr[10]; // 可以用一个bool数组保存所有n-1个符号,我们用true表示加号"+",用false表示减号"-"。
bool found = false; // 表示是否找到一组解,如果没找到的话需要在最后输出"None"
// dfs函数,保存两个状态:deep表示递归深度,就是枚举到第几个数字左边的符号;sum表示之前部分表达式的值。
// 如果枚举完成后sum的值刚好为0,则输出这组方案。我们需要在搜索的过程中用opr数组保存状态。
void dfs(int deep, int sum) {
// 请在下面的条件表达式中填上对应的值。
if (deep == n) {
if (sum == 0) {
found = true;
// 请在下面将最终方案输出,方案格式参照题目描述。
// 最后记得换行哦。
for(int i=1;i<=n-1;i++){
if(opr[i])
printf("%d+",i);
else
printf("%d-",i);
}
printf("%d\n",n);
}
return ;
}
// 请在下面的语句中填出正确的逻辑。
opr[deep] = true;
dfs( deep+1, sum+deep+1);
opr[deep] = false;
dfs( deep+1 , sum-deep-1 );
}
// main函数请自己完成哦,加油~
int main() {
while(scanf("%d",&n)!=EOF){
found=false;
dfs(1,1);
if(found==false)
printf("None\n");
}
return 0;
}