初探深度优化搜索--小白版

为什么是小白版?
因为我也是刚学会,也就刚做完一道题

深搜

深搜是什么
简单地说,就是一种搜索的方式。
是一种怎样的搜索方式呢?
用一句歌词讲就是我撞了南墙才会回头
直接举个例。
给你1、2、3三个数字,给出每一种排序。
当然答案是123、132、213、231、312、321.
怎么用深搜这种撞墙思维来解这个题呢?
深搜要有一个开始的地方(也就是你去撞南墙的起点,你总得从一个地方去撞南墙是吧)
我一般都在心中模拟一个起点,比如0。有了起点就开始去撞吧,一共我们要选择三个数字,第一次我们有三个选择,我们第一个数字选择1,第二次有两个选择,我们选择2,第三次剩下一个选择,我们选择3了。(有了答案123)现在,我们没有数字可以选择了,所以我们就撞到南墙了。那么我们就回头吧,回到第三次选择,我们发现除了3没有别的选择,但我们选过3了,好马不吃回头草,不能再选它(再选就重复选择了),所以我们只能再退,退回第二次选择,我们原本选择的2,我们发现我们可以在第二次选择3,那就选择3吧,所以第三次我们选择2。那么就有了132,又撞了是吧,再次回头,但我们发现回到第二次我们也只有选过的2、3可以选,怎么办?那就继续回头吧,回到第一次,我们可以选择第一次没有选择的2、3,所以我们选择2,继续去撞南墙(此处省略-----------)
看到这里,深搜是什么大概理解了吧
看一道题消化一下,如果你是第一次学深搜那可以要多花一点时间理解代码
点击查看题目>>来自洛谷

#include <bits/stdc++.h>

using namespace std;
int n;
int vis[20];
int add[100];
int jian[100];
int ans[20];
int flag=0;
void dfs(int row);
int main()
{
    scanf("%d",&n);
    dfs(1);
    printf("%d\n",flag);
    return 0;
}
void dfs(int row)
{
    if(row>n)
    {
        flag++;
        if(flag<=3)
        {
            for(int i=1;i<=n;i++)
            {
                if(i==1)
                    printf("%d",ans[i]);
                else
                    printf(" %d",ans[i]);
            }
            printf("\n");
        }
        return ;
    }
    for(int i=1;i<=n;i++)
    {
        if(add[row+i+20]==0&&jian[row-i+20]==0&&vis[i]==0)
        //下标都加20防止jian的下标为负
        {
            add[row+i+20]++;
            jian[row-i+20]++;
            ans[row]=i;
            vis[i]=1;
            dfs(row+1);
            vis[i]=0;
            add[row+i+20]--;
            jian[row-i+20]--;
        }
    }
}

发布了44 篇原创文章 · 获赞 13 · 访问量 2352

猜你喜欢

转载自blog.csdn.net/NEFU_kadia/article/details/104116878