赞
踩
最近在开始恢复刷一些题,难度不是很大,康复训练了属于是。
今天偶然遇到三道类似的题,大概就是利用递归进行深度搜索,搜索的同时带一定的回溯剪枝来缩短搜索时长。ac掉第一道后,剩下两道稍微改了改也很神奇地秒掉了,所以想来记录一下,希望对大家有帮助。
一个楼梯共有 n 级台阶,每次可以走一级或者两级,问从第 0 级台阶走到第 n 级台阶一共有多少种方案。
共一行,包含一个整数 n。
共一行,包含一个整数,表示方案数。
1≤n≤15
5
8
定义变量:
cnt用来记录当前方案数
k代表当前已走的台阶数
搜索路径:
走楼梯有1步\2步两种选择,因此有jump(n,k+1)和jump(n,k+2)两种递归方式
剪枝:
若当前已走的台阶数>总共的台阶数(k>n),则剪枝,即return;
#include <iostream> #include <cstring> #include <algorithm> using namespace std; int cnt = 0; //记录当前方案数 void jump(int n,int k) { if(k==n) cnt++;//若已到达终点,cnt++ else if(k>n) return;//若当前已走的台阶数>总共的台阶数,则剪枝 else //两种搜索路径 { jump(n,k+1); jump(n,k+2); } } int main() { int n; cin>>n; jump(n,0);//从起点开始搜索 cout<<cnt<<endl; return 0; }
给定一个 n×m 的方格阵,沿着方格的边线走,从左上角 (0,0) 开始,每次只能往右或者往下走一个单位距离,问走到右下角 (n,m) 一共有多少种不同的走法。
共一行,包含两个整数 n 和 m。
共一行,包含一个整数,表示走法数量。
1≤n,m≤10
2 3
10
定义变量:
cnt用来记录当前方案数,k代表当前所在的行数,p代表当前所在的列数
搜索路径:
走放个有往右或往下两种选择,因此有 walk(n,m,k+1,p)和walk(n,m,k,p+1)两种递归方式
剪枝:
若当前行或列走出边界值(k>n || p>m),则剪枝,即return;
#include <iostream> #include <cstring> #include <algorithm> using namespace std; int cnt = 0; void walk(int n,int m,int k,int p)//递归深度搜索 { if(k==n && p==m) cnt++; //若已到达终点,cnt++ else if(k>n || p>m) return; //若当前行或列走出边界值(k>n || p>m),则剪枝 else //两种搜索路径 { walk(n,m,k+1,p); walk(n,m,k,p+1); } } int main() { int n,m; cin>>n>>m; walk(n,m,0,0); //从(0,0)点开始走 cout<<cnt<<endl; return 0; }
给定一个整数 n,将数字 1∼n 排成一排,将会有很多种排列方法。
现在,请你按照字典序将所有的排列方法输出。
共一行,包含一个整数 n。
按字典序输出所有排列方案,每个方案占一行。
1≤n≤9
3
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
定义变量:
定义一个nums数组用于保存当前元素,is_visited数组用于记录当前元素是否被访问过,u记录当前已经存入nums的数的数量
搜索路径:
只要is_visited为0即未被搜索过,就可以进行搜索,因此递归方式为Permutations(u+1,n,nums,is_visited);
注意:
递归之前要将 is_visited[i] 设为1,即在当前路径下设置已经访问过
并且递归过后一定要恢复现场!!
即:将is_visited[i]再设为0,因为下次递归到这个数时为一条全新的路径
剪枝:
因为nums定义时就只有n个,递归过程中也不存在超出范围的情况,本题无需剪枝。
#include <iostream> using namespace std; void Permutations(int u,int n,int nums[],int is_visited[])//递归深度搜索 { if(u==n) //nums数组已满,到达终点,输出答案 { for(int i =0;i<n;i++) { cout<<nums[i]<<" "; } cout<<endl; } else { for(int i = 0;i<n;i++) //递归搜索时从头开始遍历 { if(is_visited[i]==0) //未被访问过 { nums[u] = i+1; //存入当前数据 is_visited[i] = 1;//在当前路径下设置已经访问 Permutations(u+1,n,nums,is_visited);//递归搜索 is_visited[i] = 0;//恢复现场:为后面的路径设置未访问 } } } } int main() { int n; cin>>n; int nums[n]; int is_visited[n] = {0}; Permutations(0,n,nums,is_visited);//从起点开始递归 //cout<<ans<<endl; return 0; }
最近才开始恢复刷一些题,没上很高的难度,有问题欢迎指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。