深搜最典型的特点是:不撞南墙不回头。
当一个问题出现多种情况的结果途径时,先对其中一种进行计算,对该情况可能出现的结果继续计算,直至抵达该问题的边界,计算出所有该情况的结果后,返回到上一步,对其他的情况做和这种情况相同的处理,将这个问题所有可能出现的结果全部计算出来
dfs的模板:
void dfs(int step)
{
判断边界;
尝试每一种可能 for(i=1;i<n;i++);
{
继续下一步dfs(step+1);
}
返回
}
例题
将n分成m个大于0的不同数的和,1 2同 2 1 视作相同的划分。
按照字典序输出所有方案。数据保证存在解,即不会出现1+2+...m > n的情况
输入
13 3
输出
1 2 10 1 3 9 1 4 8 1 5 7 2 3 8 2 4 7 2 5 6 3 4 6
思路
可以将输出的n个数当作一个数组,从第一个输出的数n开始第二个数从n+1开始第三个数从n+3开始进行深搜,每一次搜索后 下一次的总数变为x-n,直至x为0时 此时 这m个数的和即x的输入值,符合条件就可以输出了。
代码
#include<bits/stdc++.h>
using namespace std;
int m,n;
int num[100]={0};
void dfs(int u,int x)
{
if(u>m+1||x<0)
{
return;
}
if(u==m+1&&x==0)
{
for(int i=1;i<m;i++)
{
printf("%d ",num[i]);
}
printf("%d\n",num[m]);
return;
}
for(int i=num[u-1]+1;i<=x;i++)
{
num[u]=i;
dfs(u+1,x-i);
}
}
int main(){
scanf("%d%d",&n,&m);
dfs(1,n);
return 0;
}
个人收获:
深搜的题目分析开始先从结果开始分析,逐步分析到输入值,可以更好的理解每一种为什么得出解题过程,而从输入值分析往往会当时分支变多使分析难度增加,增大分析成本。