递归应用示例

递归算法虽然容易理解,但我们可能时常忘记使用它。记得算法课上老师讲过的场景:斐波那契数列,汉诺塔这两个例子,但其实不止这两个应用,进制转换,切饼,放苹果等问题都可以用它来求解。递归算法最明显特征是当前计算结果是基于前一个计算结果求解的,因此,我们需要找出递推关系式以及边界。

进制转换

下面是一个求解二进制的程序代码

#include<iostream>
using namespace std;

void convert(int n) {
	if ((n / 2) != 0) {
		convert(n / 2);
		cout << n % 2;
	}
	else cout << n;
}

int main() {
	int x;
	cin >> x;
	convert(x);
	return 0;
}

放苹果

题目描述

把M个同样的苹果放进N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
注意:5,1,1和1,5,1是同一种分法。输入:7 3,输出:8

这道题看上去貌似是数学上的排列组合问题,哎,想了半天没想到咋解的。我的高中数学呀。。。
我们先假设有一个函数f(m, n)能告诉我答案,假设盘子数N>苹果数M,则苹果的分法与多出的盘子无关,f(m, n)=f(m, m);如果苹果数M>=盘子数N,因为允许盘子为空,所以这种情况等于有盘子空着的分法加上没盘子空着的分法之和。有盘子空着时,f(m, n)=f(m, n-1)(假设至少有一个盘子空着);没有盘子空着时,说明每个盘子至少有一个苹果,此时苹果的分法与每个盘子至少放着的那只苹果无关,f(m, n)=f(m-n, n)。有了分析,代码就比较好理解了。

#include<iostream>
using namespace std;

int count(int m, int n) {
	if (m <= 0 || n <= 1) return 1;
	if (m < n)
		return count(m, m);
	else
		return count(m, n - 1) + count(m - n, n);
}

int main() {
	int apples, plates;
	cin >> apples >> plates;
	cout << count(apples, plates);
	return 0;
}
posted @ 2019-01-26 23:17  暮雪&&如霜  阅读(217)  评论(0编辑  收藏  举报