zoukankan      html  css  js  c++  java
  • DFS--基本入门模板 和 例题 (绝对入门) (最全)

    以下是全网收集整理的和自己写的部分,绝对保证dfs轻松入门。 

    核心代码:

    关于dfs参数问题,什么在变化,就把什么设置成参数。

    void dfs()//参数用来表示状态  
    {  
        if(到达终点状态)  
        {  
            ...//根据题意添加  
            return;  
        }  
        if(越界或者是不合法状态)  
            return;  
        if(特殊状态)//剪枝
            return ;
        for(扩展方式)  
        {  
            if(扩展方式所达到状态合法)  
            {  
                修改操作;//根据题意来添加  
                标记;  
                dfs();  
                (还原标记);  
                //是否还原标记根据题意  
                //如果加上(还原标记)就是 回溯法  
            }  
    
        }  
    }  

     dfs全排列:

    #include<iostream>
    #include<cmath>
    using namespace std;
     
    int p[10]={0};
    bool vis[10]={0};
    int n;
    void dfs(int x)
    {
    	if (x==n+1)
    	{
    		for(int i=1;i<=n;i++)
    		cout<<p[i]<<" ";
    		cout<<endl;
    		return ;
    	}
    	
    	for (int i=1;i<=n;i++)
    	{
    		if (vis[i]==false  )
    		{
    			p[x] = i;
    			vis[i] = true;
    			dfs(x+1);
    			vis[i] = false;
    		}
    	}
    }
     
    int main()
    {
    	
    	while (cin>>n)
    	{
    		dfs(1);
    	}
    	return 0;
    }

     在全排列的代码基础上    如果要求是顺序输出,则要剪枝,(只需要加一句代码):

    #include<iostream>
    #include<cmath>
    using namespace std;
    
    int p[10]={0};
    bool vis[10]={0};
    int n;
    void dfs(int x)
    {
    	if (x==n+1)
    	{
    		for(int i=1;i<=n;i++)
    		cout<<p[i]<<" ";
    		cout<<endl;
    		return ;
    	}
    	
    	for (int i=1;i<=n;i++)
    	{
    		if (vis[i]==false  && i>p[x])  //加上这句代码,也就是剪枝,可以避免下面的递归
    		{
    			p[x] = i;
    			vis[i] = true;
    			
    			dfs(x+1);
    			vis[i] = false;
    		}
    	}
    }
    
    int main()
    {
    	n=4;
    	dfs(1);
    	return 0;
    }
    
    
    
    

    dfs 全排列的巧妙运用:

    问题 C: 【递归入门】组合+判断素数

    时间限制: 1 Sec  内存限制: 128 MB
    提交: 205  解决: 77
    [提交][状态][讨论版][命题人:外部导入]

    题目描述

    已知 n 个整数b1,b2,…,bn

    以及一个整数 k(k<n)。

    从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。

    例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:
        3+7+12=22  3+7+19=29  7+12+19=38  3+12+19=34。
      现在,要求你计算出和为素数共有多少种。

    例如上例,只有一种的和为素数:3+7+19=29。

    输入

    第一行两个整数:n , k (1<=n<=20,k<n) 
    第二行n个整数:x1,x2,…,xn (1<=xi<=5000000) 

    输出

    一个整数(满足条件的方案数)。 

    样例输入

    4 3
    3 7 12 19
    

    样例输出

    1
    #include<iostream>
    #include<cstring>
    using namespace std;
    
    bool isprime(int n)
    {
    	if (n<=1)
    	return false;
    	for (int i=2;i*i<=n;i++)
    	if (n%i==0)
    	return false;
    	
    	return true;
    }//判断素数 
    
    int a[22];
    int b[22];
    int p[22]; 
    bool vis[22];
    int n,k,sum,ans;
    
    void dfs(int index)
    {
    	if (index==k+1)
    	{
    		if (isprime(sum))
    		ans++;//看是否加起来是素数 
    		for (int i=1;i<=index-1;i++)
    		cout<<p[i]<<" ";
    		cout<<endl;
    		return ;
    	}
    	
    	
    	for (int i=1;i<=n;i++)
    	{
    		if (vis[i]==false  &&  i>p[index-1])//保证这个排列是按顺序来的,避免重复计算导致答案错误 
    		{
    			p[index] = i;
    			vis[i] = true;
    			sum+=a[i];//最巧妙的地方,,利用全排列的排列过程中,来加上我输入的数字 
    			
    			dfs(index+1);
    			
    			vis[i] = false;
    			sum-=a[i];//有加就有减 
    		}
    	}
    }
    
    
    int main()
    {
    	memset(b,0,sizeof(b));
    	memset(vis,0,sizeof(vis));
    	cin>>n>>k;
    	for (int i=1;i<=n;i++)
    	cin>>a[i],p[i]=i;//一开始要从第一个排列填好  才开始遍历 ,这与传统的dfs全排列做了点变化 
    	
    	ans=0;
    	
    	dfs(1);
    	cout<<ans<<endl;
    	
    	return 0;
    } 
    //妈的,这个答案真巧妙 
    

    初学dfs:先做最最最基础的题: http://codeup.cn/contest.php?cid=100000608

    做完了,你就入门了(绝对没有比这更基础的题了)

    然后再做下面的题:

    题型分类:

    写过这些入门题后,我们可以将DFS题分为两大类: 


    1 . 地图型:这种题型将地图输入,要求完成一定的任务。因为地图的存在。使得题意清楚形象化,容易理清搜索思路。

    2 . 数据型:这种题型没有给定地图,一般是一串数字或字母,要求按照一定的任务解题。相对于地图型,这种题型较为抽象,需要在数据中进行搜索。数据以数组的形式存储,那么只要将数组也当作一张图来进行搜索就可以了。

  • 相关阅读:
    winform访问https webservice
    rabbitMQ访问失败
    Redis断线测试
    微信消息推送
    线程控制
    Oracle.ManagedDataAccess.dll折腾了我两天
    IPC网络摄像机rtsp视频流web上H5播放方法
    微软补丁下载网站(备忘)
    ABP vnext 种子文件更新
    ABP vnext 使用Swagger账号登录时Chrome浏览器提示【The cookie 'XSRF-TOKEN' has set 'SameSite=None' and must also set 'Secure'.】错误,不能跳转登录
  • 原文地址:https://www.cnblogs.com/Romantic-Chopin/p/12451479.html
Copyright © 2011-2022 走看看