😊😊 😊😊
不求点赞,只求耐心看完,指出您的疑惑和写的不好的地方,谢谢您。本人会及时更正感谢。希望看完后能帮助您理解算法的本质
😊😊 😊😊
蜜蜂路线
题目背景
无
题目描述
一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房 m m m 开始爬到蜂房 n n n, m < n m<n m<n,有多少种爬行路线?(备注:题面有误,右上角应为 n − 1 n-1 n−1)
输入格式
输入 m , n m,n m,n 的值
输出格式
爬行有多少种路线
样例 #1
样例输入 #1
1 14
样例输出 #1
377
提示
对于100%的数据, 1 ≤ M , N ≤ 1000 1 \le M,N\le 1000 1≤M,N≤1000
小白到进阶各种解法:
一、暴搜:😊
思路:
- 递归的出口:走到 n n n 的时候。
- 关键在于递归的计算,很多同学会以为是一个二维的矩阵上递归搜索,实际不然,可以抽象成一个一维的序列来走,即之前的爬楼梯一样的,每次可以走一步,也可以走两步!
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e3 + 10;
int n, m;
int dx[] = {0,-1};
int dy[] = {1, 0};
int cnt;
void dfs (int u)
{
if (u == n)
{
cnt ++;
return;
}
if (u+1 <= n) //+1 == 向下走!
dfs (u+1);
if (u+2 <= n) //+2 == 向右走!
dfs (u+2);
}
int main()
{
cin >> m >> n;
dfs (m);
cout << cnt << endl;
return 0;
}
二、记忆化搜索:😊
思路:
- 记忆化数组: f [ i ] f[i] f[i]表示从点 i i i 到点 n n n 的方案数!
- 又有个坑:请看下面的代码:
请问我们初始的时候, f 数组 = − 1 f数组=-1 f数组=−1,那么就不能在第一个 i f if if判断的递归里面写 f [ u ] + = d f s ( u + 1 ) f[u]+=dfs(u+1) f[u]+=dfs(u+1),计算错误,造成很大的误差! - 如果初始化为: m e m s e t ( f , 0 , s i z e o f ( f ) ) ; memset (f, 0, sizeof(f)); memset(f,0,sizeof(f)); 则这么写: f [ u ] + = d f s ( u + 1 ) f[u]+=dfs(u+1) f[u]+=dfs(u+1) 没有任何问题!
if (u+1 <= n) f[u] = dfs(u+1);
if (u+2 <= n) f[u] += dfs(u+2);
memset (f, -1, sizeof(f));
代码:缺个高精度,暂时未学,学了就补上!
#include<iostream>
#include<cstring>
using namespace std;
const int N = 1e3 + 10;
int f[N];
int n, m;
int dfs (int u)
{
if (f[u] != -1) return f[u];
if (u == n){
f[u] = 1;
return f[u];
}
if (u+1 <= n)
f[u] = dfs(u+1);
if (u+2 <= n)
f[u] += dfs(u+2);
return f[u];
}
int main()
{
memset (f, -1, sizeof(f));
cin >> m >> n;
cout << dfs (m) << endl;
return 0;
}
三、本题考察算法:😊
思路:
-
从子问题记录到原问题,请问求出 f [ n ] f[n] f[n]需要什么?
-
由图中的二维矩阵我们可以看出 +1 是往右走,+2 是往下走的,且由于每次只能从标号小的地方往标号大的地方走,所以到达终点 n n n 可以由 n − 1 或 n − 2 n-1\ 或\ n-2 n−1 或 n−2转移过来!
-
设 f [ i ] f[i] f[i] 表示从起点 m m m 到达终点 i i i 的所有方案。所以说可得:
f [ i ] = f [ i − 1 ] + f [ i − 2 ] ; \\f[i] = f[i-1] + f[i-2]; f[i]=f[i−1]+f[i−2]; -
记得初始化,因为: f [ 1 ] , f [ 0 ] f[1],f[0] f[1],f[0]不能递推!
代码:
#include<iostream>
using namespace std;
const int N = 1e3 + 10;
int f[N];
int n, m;
int main()
{
cin >> m >> n;
//初始化:
f[1] = 1;
for (int i=2; i <= n; i ++)
f[i] = f[i-1] + f[i-2];
cout << f[n];
return 0;
}