刚接触算法,有没有被递归又循环的dfs吓到?没关系,几个例题就可以彻底掌握!

1-n的全排列,如输入3,按顺序对1-3进行排列

- //枚举
- #include
- #include
- #include
- using namespace std;
- const int N=10;
- int n;
- bool st[N];//true选过 ,false是没选过
- int arr[N];//存的是答案
- void dfs(int x)
- {
- if(x>n)
- {for(int i=1;i<=n;i++)
- {
- printf("%5d",arr[i]);//长宽5
- }
- printf("\n");
- return ;
- }
- for(int i=1;i<=n;i++)
- {
- if(!st[i])
- {
- st[i]=true;
- arr[x]=i;
- dfs(x+1);
- st[i]=false;
- arr[x]=0;
- }
- }
- }
- int main()
- {
- scanf("%d",&n);
- dfs(1);
-
- return 0;
- }
题目:
答案:
- //选数
- //剪枝
- #include
- #include
- #include
- using namespace std;
- const int N=30;
- int k,n;
- int q[N];
- int arr[N];
- int res=0;
-
- bool is_prim(int sum)
- {
- if(sum<2)return false;
- for(int i=2;i<=sum/i;i++)
- {
- if(sum%i==0)return false;
- }
- return true;
- }
- //求组合数,x表示当前到了哪个位置
- //start表示从几开始枚举
- void dfs(int x,int start)
- {
- if(((x-1)+n-start+1)
- {
- return ;
- }
- if(x>k){
- int sum=0
- for(int i=1;i<=k;i++)
- {
- sum+=arr[i];
- }
- if(is_prim(sum))//是素数+1
- {
- res++;
- }
- }
- for(int i=start;i<=n;i++)
- {
- arr[x]=q[i];
- dfs(x+1,i+1);//继续向下,深度优先
- arr[x]=0;//恢复现场
- }
- }
-
- int main()
- {
- scanf("%d %d",&n,&k);
- dfs(1,1);
- printf("%d\n",res);
- return 0;
- }