建议和上一次博客一起看,便于更好理解递归。
这是我从洛谷上找的题,p1010.
我们看到,第一次将一个数据拆成由2组成的序列,再把2()里面的值再次拆解直到2或者2(0)或者2+2(0)结束。很明显,括号里面做法和第一次对数据拆解用的应该是同一个方法,因此使用递归分治。
做法:
先上代码(能体现分治思想的片段)吧:(主要想体现分治思路)
#include <iostream>
#define ll long long
using namespace std;
inline int pow1(int a) {
return 1 << a;
}
void power(ll n) {
int i;
if (n == 0)return;
for (i = 0; pow1(i) <= n; i++) {}
i--;
if (i == 1)s += "2";
if (i == 0)s += "+2(0)";
if (i > 1) {
s += "2(";
power(i);//一号递归处
s += ")+";
}
power(n - pow1(i));//二号递归处
}
思路:首先,先找到比这个数小的最大二次幂对应的幂是谁,再将这个幂进入递归调用,随后补玩括号后,再用n值减去二次幂,把剩下的数据按原方式进行递归调用,直到n == 0(下面我画个图来解释一下)结束。
我在调用的时候发现当传进去0的时候就可以返回了(如图右叶部分,最终结果都为0)
递归分治解释:{当传进去137的时候,i是7进入第二次递归调用,后来i变成2再次进入一号递归处并开启第二层递归,这层里面i =1,随后进入二号递归处,n变为了0。结束递归。
由于递归是抵达return后逐级返回,他的上一级是i= 2,但是它不会停留(因为这层递归已经全部走完,二号递归处后面没有了代码,因而会再度返回到i= 7那一层递归,这一层递归不同的是,它仅仅进行了一号递归,因而在进行一号递归后面的全部代码,这时候,n= 7,i= 2,进入第二层递归。)}
递归是逐级返回,所谓的逐级,就是只要调用一次该函数就算一级递归。return会返回一级。
这是我对递归分治的一些看法,主要以理解递归为主。