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--------------------------------------------------------------------