《算法笔记》4.3小节——算法初步->递归
A 吃糖果
题目描述
名名的妈妈从外地出差回来,带了一盒好吃又精美的巧克力给名名(盒内共有 N 块巧克力,20 > N >0)。
妈妈告诉名名每天可以吃一块或者两块巧克力。
假设名名每天都吃巧克力,问名名共有多少种不同的吃完巧克力的方案。
例如:
如果N=1,则名名第1天就吃掉它,共有1种方案;
如果N=2,则名名可以第1天吃1块,第2天吃1块,也可以第1天吃2块,共有2种方案;
如果N=3,则名名第1天可以吃1块,剩2块,也可以第1天吃2块剩1块,所以名名共有2+1=3种方案;
如果N=4,则名名可以第1天吃1块,剩3块,也可以第1天吃2块,剩2块,共有3+2=5种方案。
现在给定N,请你写程序求出名名吃巧克力的方案数目。
输入
输入只有1行,即整数N。
输出
可能有多组测试数据,对于每组数据,
输出只有1行,即名名吃巧克力的方案数。
样例输入
1
2
4
样例输出
1
2
5
代码提交
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<fstream>
using namespace std;
int candy(int M) {
if(M == 1) return 1;
if(M == 2) return 2;
return candy(M-1) + candy(M-2);
}
int main() {
// freopen("d://in.txt","r",stdin);
int N;
while(scanf("%d",&N)!=EOF) {
int ans = candy(N);
printf("%d\n",ans);
}
return 0;
}
这个题型与斐波那契数列的原理和算法一致,主要是找出题目中给出的规律而不是死磕题目的具体意思
B 数列
题目描述
编写一个求斐波那契数列的递归函数,输入n 值,使用该递归函数,输出如下图形(参见样例)。
输入
输入第一行为样例数m,接下来有m行每行一个整数n,n不超过10。
输出
对应每个样例输出要求的图形(参见样例格式)。
样例输入
1
6
样例输出
0
0 1 1
0 1 1 2 3
0 1 1 2 3 5 8
0 1 1 2 3 5 8 13 21
0 1 1 2 3 5 8 13 21 34 55
代码提交
#include <iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
using namespace std;
int F(int n) {
if(n==0)
return 0;
else if(n==1)
return 1;
else
return F(n-1)+F(n-2);
}
int main()
{
int m;
scanf("%d",&m);
while(m--){
int n,i,j;
scanf("%d",&n);
for(i=0;i<n;i++){
for(j=0;j<2*(n-i-1);j++){
printf(" ");
}
for(int k=0;k<2*(i+1)-1;k++){
printf("%d",F(k));
if(k<2*(i+1)-1) printf(" ");
}
printf("\n");
}
}
return 0;
}
和题目A一样属于契波那契数列,唯一复杂的地方在于循环打印空格和每行不同的数值。
C 神奇的口袋
题目描述
有一个神奇的口袋,总的容积是40,用这个口袋可以变出一些物品,这些物品的总体积必须是40。John现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an。John可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的口袋,John就可以得到这些物品。现在的问题是,John有多少种不同的选择物品的方式。
输入
输入的第一行是正整数n (1 <= n <= 20),表示不同的物品的数目。接下来的n行,每行有一个1到40之间的正整数,分别给出a1,a2……an的值。
输出
输出不同的选择物品的方式的数目。
样例输入
2
12
28
3
21
10
5
样例输出
1
0
代码提交
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
const int maxn = 21;
int count;
int N;
int nowremnant = 40;
int goods[maxn];
int generateP(int index){
if(nowremnant < 0){
return 0;
}
else if(nowremnant == 0){
count++;
return 0;
}
if(index == N) return 0;
for(int i = index; i < N; i++){
nowremnant = nowremnant - goods[i];
generateP(i+1);
nowremnant = nowremnant + goods[i];
}
}
int main(void){
while(~scanf("%d",&N)){
count = 0;
for(int i = 0; i < N; i++) scanf("%d",&goods[i]);
generateP(0);
printf("%d\n",count);
}
}
思路
这道题的思路类似于全排序,在所有不同的排序里算出40减去排序中的数值,如果大于0则符合条件,count+。
由于之前在看书上例子的时候一直没法理解这个递归是如何实现全排列的,于是在刷到这种类型的题时又把全排列算法给理解了一遍。
这个图片是在一个博主那看到的,编译过程描述的非常详细,也让我弄懂了这个算法。
D 八皇后
菜鸡表示真的好难,占个坑,说不定以后会懂