递推、逆推算法
- 一、斐波那契数列
- 1. 基础知识
- 2. 审题
- 3. 参考答案
- 二、P2437 蜜蜂路线
- 1. 审题
- 2. 参考答案
- 三、杨辉三角
- 1. 基础知识
- 2. 审题
- 3. 参考答案
- 四、猴子分桃
- 1. 审题
- 2. 思路
- 3. 参考答案
- 递推算法
- 递归算法
- 五、偶数个5
- 1. 审题
- 2. 参考答案
- 习题
- 1. 赶鸭子
- 1.1 审题
- 1.2 参考答案
- 2. 台阶问题
- 2.1 审题
- 2.2 参考答案
- 3. 偶数个3
- 1. 审题
- 2. 参考答案
- 彩蛋
一、斐波那契数列
1. 基础知识
斐波那契数列是由 < 1 , 1 , 2 , 3 , 5 , 8 , . . . > <1, 1, 2, 3, 5, 8, ...> <1,1,2,3,5,8,...> 构成的一串无线序列,其基础项是前两项 1 1 1 和 1 1 1,从 3 3 3 开始求解方法为 f ( n ) = f ( n − 1 ) + f ( n − 2 ) f(n) = f(n-1) + f(n-2) f(n)=f(n−1)+f(n−2)。
2. 审题
题目描述
斐波那契数列是这样的数列:数列的第一项和第二项都为 1 1 1,接下来的每一项都等于前面两项之和。给出一个整数 n n n,输出斐波那契数列前n项。
输入描述
一行,包含一个整数 n n n
输出描述
一行,斐波那契数列前 n n n 项,两个数字之间以一个空格隔开
样例1
输入
4
输出
1 1 2 3
提示
1 ≤ n ≤ 20 1 \le n \le 20 1≤n≤20
3. 参考答案
#include <iostream>
using namespace std;long long n;
long long f[25] = {0, 1, 1};int main()
{cin >> n;for (int i = 1; i <= n; i++){if (i <= 2){cout << 1 << " ";continue;}f[i] = f[i-1] + f[i-2];cout << f[i] << " ";}return 0;
}
二、P2437 蜜蜂路线
1. 审题
题目描述
一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房 M M M 开始爬到蜂房 N N N, M < N M<N M<N,有多少种爬行路线?例如从蜂房 1 1 1 爬到蜂房 3 3 3,有两种方法,分别是 1 − 3 1-3 1−3; 1 − 2 − 3 1-2-3 1−2−3。
输入描述
一行,包含两个正整数 M M M 和 N N N,表示蜜蜂爬行的起点和终点。
输出描述
一个整数,表示爬行路线有多少种
样例1
输入
1 14
输出
377
提示
1 ≤ M < N ≤ 20 1 \le M < N \le 20 1≤M<N≤20
2. 参考答案
#include<iostream>
using namespace std;int s, e;
int l[25] = {0, 1, 2};int main()
{cin >> s >> e;for (int i = 3; i <= e-s+1; i++){l[i] = l[i-1] + l[i-2];}cout << l[e-s];return 0;
}
三、杨辉三角
1. 基础知识
1 1 1
1 1 1 1 1 1
1 1 1 2 2 2 1 1 1
1 1 1 3 3 3 3 3 3 1 1 1
1 1 1 4 4 4 6 6 6 4 4 4 1 1 1
规律
f ( i , j ) = f ( i − 1 , j − 1 ) + f ( i − 1 , j ) f(i,j) = f(i-1,j-1)+f(i-1,j) f(i,j)=f(i−1,j−1)+f(i−1,j)
用文字表述,即某一项相当于这一项左上方那一项加上这一项上方那一项。
基础项
仅仅只有第一行的 1 1 1 。
2. 审题
题目描述
满足如下图所示规律的三角形称为杨辉三角。输入一个正整数 n n n 表示三角形的层数,在控制台打印出该杨辉三角。
输入描述
输入文件名:
tria.in
一行,包含一个正整数 n n n( 0 < n < 21 0<n<21 0<n<21)
输出描述
输出文件名:
tria.out
杨辉三角前 n n n 行
样例1
输入
3
输出
1 1 1 1 2 1
提示
0 < n < 21 0<n<21 0<n<21
3. 参考答案
#include <iostream>
#include <cstdio>
using namespace std;int n;
int a[25][25];int main()
{freopen("tria.in", "r", stdin);freopen("tria.out", "w", stdout);cin >> n;a[0][0] = 1; // 基础项for (int i = 1; i <= n; i++){for (int j = 1; j <= i; j++){a[i][j] = a[i-1][j-1] + a[i-1][j];cout << a[i][j] << " ";}cout << endl;}fclose(stdin);fclose(stdout);return 0;
}
四、猴子分桃
1. 审题
题目描述
海滩上有一堆桃子, N N N 只猴子来分。第一只猴子把这堆桃子中的一个扔入海中,然后将剩余的桃子平均分成两份,最后这只猴子拿走了 1 1 1 份。第二只猴子来了接着把剩下的桃子中的一个扔入海中,然后把剩余的桃子平均分成 2 2 2 份,开开心心拿走了 1 1 1 份。第三、第四、……,第 N N N 只猴子都是将剩下的桃子中的一个扔入海中,然后将剩余的桃子平均分成 2 2 2 份,并拿走其中的 1 1 1 份。最后只剩下 1 1 1 个桃子。编写程序,输入猴子的数量 N N N,输出海滩上原有多少桃子。
输入描述
一行,包含一个正整数 N N N( 0 < N < 21 0<N<21 0<N<21)
输出描述
一个整数, 海滩上原有多少桃子
样例1
输入
2
输出
7
提示
0 < N < 21 0<N<21 0<N<21
2. 思路
通过逆推的方式,我们求得:
f ( n ) = f ( n − 1 ) × 2 + 1 f(n)=f(n-1)\times2+1 f(n)=f(n−1)×2+1
3. 参考答案
递推算法
#include <iostream>
using namespace std;int n;
int a[25];int main()
{cin >> n;a[0] = 1;for (int i = 1; i <= n; i++){a[i] = a[i-1] * 2 + 1;}cout << a[n];return 0;
}
递归算法
#include <iostream>
using namespace std;int n; // n记得开全局// f(n)表示第n只猴剩下的桃子
int f(int x)
{if (x == n){return 1;}return f(x+1) * 2 + 1;
}int main()
{cin >> n;cout << f(0);return 0;
}
例如,按照输入样例的 2 2 2,程序会这么执行:
f ( 0 ) = f ( 1 ) × 2 + 1 f(0)=f(1)\times 2+1 f(0)=f(1)×2+1
f ( 1 ) = f ( 2 ) × 2 + 1 f(1)=f(2)\times 2+1 f(1)=f(2)×2+1
f ( 2 ) = 1 f(2)=1 f(2)=1
f ( 1 ) = 1 × 2 + 1 = 3 f(1)=1 \times 2 + 1=3 f(1)=1×2+1=3
f ( 0 ) = 3 × 2 + 1 = 7 f(0)=3 \times 2 + 1=7 f(0)=3×2+1=7
五、偶数个5
1. 审题
题目描述
在所有的 n n n 位数种,有多少个数中有偶数个数字 5 5 5?请让这个结果对 11111 11111 11111 进行取模。
输入描述
一行,包含一个正整数 n n n( 0 < n < 50 0<n<50 0<n<50)
输出描述
一个整数,输出有多少个数中有偶数个数字 5 5 5。
样例1
输入
2
输出
73
提示
0 < n < 50 0<n<50 0<n<50
2. 参考答案
#include <iostream>
using namespace std;int n;
int ou[55];
int ji[55];int main()
{cin >> n;ou[1] = 9;ji[1] = 1;for (int i = 2; i <= n-1; i++){ou[i] = (ou[i-1] * 9 + ji[i-1] * 1) % 11111;ji[i] = (ou[i-1] * 1 + ji[i-1] * 9) % 11111;}cout << (ou[n-1] * 8 + ji[n-1] * 1) % 11111;return 0;
}
习题
1. 赶鸭子
1.1 审题
一个人赶着鸭子到每个村庄卖,每经过一个村子卖去所赶鸭子的一半又一只,经过一个村子后还剩 n n n 只鸭子,求出发时共赶多少只鸭子。
1.2 参考答案
#include <iostream>
using namespace std;int n;int main()
{cin >> n;for (int i = 1; i <= 7; i++){n = (n + 1) * 2;}cout << n;
}
2. 台阶问题
2.1 审题
题目描述
台阶总共有 n n n 级,一次可以上 1 1 1 级,也可以上 2 2 2 级,也可以上 3 3 3 级,上 n n n 级台阶,总共有多少种走法?
输入描述
共 1 1 1 行,为一个正整数 n n n,表示台阶的数量。
输出描述
共一行,为一个正整数,表示走法数量。
样例1
输入
3
输出
4
提示
0 < n < 21 0<n<21 0<n<21
2.2 参考答案
#include <iostream>
using namespace std;int n;
int a[25] = {0, 1, 2, 4};int main()
{cin >> n;for (int i = 4; i <= n; i++){a[i] = a[i-1] + a[i-2] + a[i-3];}cout << a[n];return 0;
}
3. 偶数个3
1. 审题
题目略
2. 参考答案
#include <iostream>
using namespace std;int n;
int ou[55];
int ji[55];int main()
{cin >> n;ou[1] = 9;ji[1] = 1;for (int i = 2; i <= n-1; i++){ou[i] = (ou[i-1] * 9 + ji[i-1] * 1) % 11111;ji[i] = (ou[i-1] * 1 + ji[i-1] * 9) % 11111;}cout << (ou[n-1] * 8 + ji[n-1] * 1) % 11111;return 0;
}
彩蛋
后期预告
下一期是模拟算法哦,千万不要错过!
C++冷知识
C++
提供了异常处理机制,允许程序在遇到错误时跳过函数调用链并执行特定的错误处理代码,以实现错误恢复和程序稳定性!