你好,2023【搜索与回溯(一)】认识+框架+例题 安排上

1.祝福

  明天(本博客写于2022.12.31)是元旦,祝各位努力认真的博主们在新的一年里事业更上一层楼!
  加油,码字人!

新年红包不能少~
https://bbs.youkuaiyun.com/topics/611453615红包请查收

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body style="background-color:red;"><img src="logo.jpg"></body>
	<br/>
	<i>  Year year2023 = new Year("2023");  </i><br/>
	<i>  year2023.is happy = true;  </i><br/>
	<i>  year2022.covid_19 = 0;  </i><br/>
	<i>  year2023.money = Float.POSITIVE_INFINITY;  </i><br/>
	<i>  year2023.run();  </i><br/>
</html>


把这个↑↑保存为logo.jpg(实在是不会在博客上传文件夹啊,大佬指点下)
~~剩下的就不用我多说,.html文件名后缀保存起来~

2.导语&认识

搜索与回溯是计算机解题中较为常用的一种算法,很多问题无法根据某种确定的计算法则来求解,可以利用搜索与回溯的技术求解。
回溯是搜索算法中的一种控制策略。它的基本思想是:为了求得问题的解,先选择某一种可能的情况向前探索,在探索过程中,一旦发现原来的选择是错误的,就退回一步重新选择,继续向前搜索,如此反复进行,直到得到解或证明无解。
如迷宫问题:进入迷宫后,先随意选择一个行进方向,一步步向前试探前进,如果碰到死胡同,说明前进方向已无路可走。这时,首先看其他方向是否还有路可走:如果有路可走,则沿该方向再向前试探;如果已无路可走,则返回一步,再看其他方向是否还有路可走。按此原则不断搜索回溯再搜索,直到找到新的出路或从原路返回入口处无解为止。

3.算法框架

递归回溯算法框架一
int search(int k)
{
	for(i=1;i<=算符种数;i++)
	if(满足条件)
	{
		if(到目的地) 
			输出解;
		else
			search(k+1);
		恢复:保存结果之前的状态{回溯一步} 
	}
}
递归回溯算法框架二
int search(int k)
{
	if(到目的地) 
		 输出解;
	for(i=1;i<=算符种数;i++)
		if(满足条件)
		{
			保存结果; 
			search(k+1);
			恢复:保存结果之前的状态{回溯一步} 
		}
}

4.例题精讲

组合的输出

时间限制: 1000 ms 内存限制: 65536 KB
【题目描述】
排列与组合是常用的数学方法,其中组合就是从n个元素中抽出r个元素(不分顺序且r≤n),我们可以简单地将n个元素理解为自然数1,2,…,n,从中任取r个数。
现要求你用递归的方法输出所有组合。
例如n=5,r=3,所有组合为:
1 2 3 1 2 4 1 2 5 1 3 4 1 3 5 1 4 5 2 3 4 2 3 5 2 4 5 3 4 5
【输入】
一行两个自然数n、r(1<n<21,1≤r≤n)。
【输出】
所有的组合,每一个组合占一行且其中的元素按由小到大的顺序排列,每个元素占三个字符的位置,所有的组合也按字典顺序。
【输入样例】
5 3
【输出样例】
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5

配图秒懂

在这里插入图片描述

参考代码
#include<bits/stdc++.h>
using namespace std;
int a[10];
bool vis[10];
int n,r;	
void dfs(int x)
{
	if(x>r)
	{
		for(int i=1;i<=r;i++)
		{
			cout<<setw(3)<<a[i];//每个元素占三个字符的位置
		}
		cout<<endl;
		return;
	}
	for(int i=a[x-1];i<=n;i++)
	{
		if(vis[i]==0)
		{
			a[x]=i;
			vis[i]=1;
			dfs(x+1);
			vis[i]=0;//回溯
		}
	}
}
int main()
{
	cin>>n>>r;
	a[0]=1;
	dfs(1);
	return 0;
}

---------------------------------------------------------------END--------------------------------------------------------------------

评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值