搜索基础讲解

前言:搜索可以解决什么样的问题?

(1) 可行解的求解(例如   POJ - 3278:中文题意 https://vjudge.net/problem/POJ-3278#author=hnshhslsh)

(2) 二维图形的移动搜索(http://codevs.cn/problem/1215/

 

1.什么是搜索?

(1) 搜索算法的解决思路是尽可能的将问题的所有的可能性列出,再在其中去寻求我们需要的结果。

(2) 这里我们主要介绍深度优先搜索(dfs)和广度优先搜索(bfs).

 

2.递归函数

<Question> 用递归的形式求取斐波那契数列第n项

图中明显进行了fib(1) —— fib(5) 的所有运算,不难看出有重复运算,因此效率还不够高。

#include <stdio.h>

int fib(int n)
{
    if (n == 1 || n == 2) return 1;   //先写出递归出口

    return fib(n - 1) + fib(n - 2);   //调用自身进行递归运算
}

int main()
{
    printf("%d\n", fib(5));           //输出fib的第5项
    return 0;
}

引入数组记录结果提高执行效率

#include <stdio.h>
#include <cstring>

int a[105];

/*fib效率改进*/

int fib(int n)
{
    if (n == 1 || n == 2) return a[n];   //先写出递归出口

    if (!a[n]) a[n] = fib(n - 1) + fib(n - 2);

    return a[n];                         //调用自身进行递归运算
}

int main()
{
    memset(a, 0 ,sizeof(a));
    a[1] = 1;
    a[2] = 1;
    printf("%d\n", fib(5));           //输出fib的第5项
    return 0;
}

!关于斐波那契数列的坑点:第X项会爆int型的数据范围。

 

<怎么写递归函数>

(1) 明确递归出口

(2) 头脑中建立“递归树”模型,思考递归过程中如何将可能性罗列出来

(3) 大量练习

 

<递归练手>

http://codevs.cn/problem/1842/

 

3.回溯(重点)

回溯是DFS(Depth-First-Search)深度优先搜索的关键思想,掌握了回溯的思想就等同于掌握了DFS基础

 

<Question> 利用DFS进行全排列生成

http://codevs.cn/problem/1294/

题解:(让大家体会dfs思想,严禁粘贴代码)

 

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int maxn = 15;

int a[maxn];
int n;
bool vis[maxn];       //该元素是否使用

void print()
{
    for (int i = 0; i < n; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
}


void dfs(int val, int inx)     //参数的含义表示将val放到下标索引为inx的位置上
{
    a[inx] = val;

    if (inx == n-1) {
        print();
        return ;
    }

    for (int i = 1; i <= n; i++) {
        if (vis[i] == false) {       //先判断i是不是被选中了
            vis[i] = true;           //纳入
            dfs(i, inx+1);
            vis[i] = false;          //不纳入
        }
    }
}

int main()
{
    scanf("%d", &n);
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++) {
        vis[i] = true;   //将元素i选入集合
        dfs(i, 0);
        vis[i] = false;  //元素i不选入集合
    }

    return 0;
}

本题坑点:体会cout与printf的输出效率

 

4.体会DFS

<Question> 经典DFS问题,走迷宫

http://codevs.cn/problem/1215/

 

5.练习

相关题目已经布置,都属于基础性题目,请大家认真完成,切勿抄袭!

http://codevs.cn/problem/2806/

http://acm.nuc.edu.cn/OJ/problem/show/1983

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水能zai舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值