递归的概念
(待填坑)
递归的两个要素
- 递归的边界
- 递归的逻辑——递归公式
递归的过程中一定有参数的变化,并且参数的变化与递归边界有关。
【例1】切蛋糕问题
描述
有n克蛋糕,分给n个人吃,每人1克。在切蛋糕的过程中,每次只允许选择一块蛋糕并将它切成两份。由于切蛋糕是项技术活,每次切蛋糕都需要消耗一定量的ATP。经过调查,把n克的切糕切成x克和(n-x)克后,需要消耗x*(n-x)单位的ATP(其中1<=x<=n,且x为整数)。问将n克蛋糕分配给n个人,总共需要消耗多少ATP?
输入
第一行有一个无符号整数t(1<=t<=50),表示有t组数据。每组数据包含一个无符号整数,n(n<=2013),n表示蛋糕的重量。
输出
对于每组数据,输出“Needs at least x ATP(s)!”,其中x表示最小需要消耗的ATP。如当x=1时,输出“Needs at least 1 ATP!”;当x=2时,输出“Needs at least 2 ATPs!”;若不需要消耗ATP,则输出“Mission Complete!”。注意这里消耗1 ATP时,输出结果中“ATP”为单数形式(ATP);消耗大于1ATP时,输出结果中“ATP”为复数形式(ATPs)。
样例输入1
2
1
2
样例输出1
Mission Complete!
Needs at least 1 ATP!
问题分析:
对于n克蛋糕分配给n个人这个任务而言:
若n=1,则无需分配,消耗的atp为0;
若n=2,则只需切一次,消耗的atp为1;
若n=3,则先分成1克和2克的蛋糕,消耗atp为2,再对2克的蛋糕进行切分,消耗atp为1,总消耗3atp;
......
若n=5,则分配方案有2种,第一种是先分成2g+3g(消耗6atp),再将2g(消耗1atp)和3g(消耗3atp)细分,总消耗10atp;第二种是先分成1g+4g,再分成1g+3g,再分成1g+2g,再分成1g+1g,总共消耗10atp。两种方案一致。
......
其实可以验证,在n一定时,无论哪种分配方式,所消耗的apt都相同。记切n克蛋糕一共需要的atp为atp(n) (n>=1),则有:
n=1,atp(n) = 0;
n>1,atp(n) = (n-1) +atp(n-1)
因此代码实现如下:
代码实现
#include <iostream>
using namespace std;
int atp(int n){
if(n==1)
return 0;
if(n>1)
return n-1+atp(n-1);
}
int main(){
int t,n;
cin >> t;
for(int i=0; i<t; i++){
cin >> n;
if(n<=0 || n>2013)
exit(0);
if(atp(n) == 0)
cout << "Mission Complete!" << endl;
else if(atp(n) == 1)
cout << "Needs at least " << atp(n) << " ATP!" << endl;
else
cout << "Needs at least " << atp(n) << " ATPs!" << endl;
}
return 0;
}