1、分治思想与递归手段
首先,分治的英文是divide and conquer, 也就是分而治之的意思,基本策略是将原问题划分为若干个规模较小而结构与原问题相同或相似的子问题,然后分别解决这些子问题,最后合并子问题的解就能得到原问题的解。
一般我们都是使用递归的手段去实现分治思想
2、递归
- 概念:通过反复调用自身函数, 但是每次都把问题范围缩小,直到范围缩小到可以直接得到边界数据的结果,然后再在返回的路上求出结果。正是因为递归与分治的思想非常接近,所以我们会递归来解决分治问题。
- 递归的两个重要概念:递归边界与递归式。递归式是将原问题分解为若干个子问题的手段,递归边界则是分解的尽头
3、递归的具体例子练习
- 阶乘: n!= n * n-1 * n-1 * ... * 1, 写成递归式就是 n! = ( n-1 ) ! * n, 可以看出跳出递归的边界就是n为1或0的情况(因为1!=0!=0 ,所以都可以作为递归边界)
#include<stdio.h> #include<iostream> using namespace std; int f(int n) { if(n == 0) return 1; //这个判定就是递归边界 else return f(n-1) * n; //f(n) = f(n-1) * n就是递归式 } int main() { int n; cin>>n; cout<<f(n)<<endl; return 0; }
-
经典例子:Fibonacci (斐波那契) 数列的第n项 F(1)=1, F(2)=2, 递推式为F(n) = F(n-1) + F(n-2), n>2
#include<stdio.h> #include<iostream> using namespace std; //Fibonacci int Fibo(int n) { if(n <= 2) return 1; //递归边界显然是n>=2 else return Fibo(n-1)+Fibo(n-2); //递归式也很简单:f(n)= f(n-1)+f(n-2) } int main() { int n; cin>>n; cout<<Fibo(n)<<endl; return 0; }
- 全排列问题: 一般把1~n这n个整数按某个顺序摆放的结果称为这n个整数的一个排列,而全排列指这n个整数能形成的所有排列。例如对1、2、3这三个整数来说,(1,2,3)
#include<iostream> using namespace std; const int N=11; int n; int q[N], st[N]; void f(int x) { if(x == n+1) { for(int i=1;i<=n;i++) { cout<<q[i]<<' '; } cout<<endl; } for(int i=1;i<=n;i++) { if(st[i] == 0) { q[x]=i; st[i]=1; f(x+1); //判断类型的递归式 st[i]=0; //这里需要回复状态 } } } int main() { cin>>n; f(1); return 0; }
- n皇后
来源:CSDN
作者:weixin_44698281
链接:https://blog.csdn.net/weixin_44698281/article/details/103240354