问题描述
小明参加了学校的趣味运动会,其中的一个项目是:跳格子。
地上画着一些格子,每个格子里写一个字,如下所示:
比赛时,先站在左上角的写着“从”字的格子里,可以横向或纵向跳到相邻的格子里,但不能跳到对角的格子或其它位置。
一直要跳到“华”字结束。 要求跳过的路线刚好构成“从我做起振兴中华”这句话。
请你帮助小明算一算他一共有多少种可能的跳跃路线呢?
答案提交
答案是一个整数,请通过浏览器直接提交该数字。
注意:不要提交解答过程,或其它辅助说明类的内容。
答案:35
解题思路:
其实就是问从左上角到右下角一共有几种走法
题解一
DFS:
#include <iostream>
using namespace std;
int ans;
int dx[2] = {0, 1};
int dy[2] = {1, 0};
void dfs(int x,int y)
{
if (x == 3 && y == 4)
{
ans ++;
return;
}
for (int i = 0; i < 2; i++)
{
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a > 3 || b < 0 || b > 4) continue;
dfs(a, b);
}
}
int main()
{
dfs(0, 0);
cout << ans << endl;
return 0;
}
题解二
记忆化搜索:
#include <iostream>
#include <cstring>
using namespace std;
int ans, f[10][10] ;
int dx[2] = {0, 1};
int dy[2] = {1, 0};
int dfs(int x,int y)
{
if(f[x][y] != -1) return f[x][y];
f[x][y] = 0;
for (int i = 0; i < 2; i ++)
{
int a = x + dx[i], b = y + dy[i];
if (a < 0 || a > 3 || b < 0 || b > 4 ) continue;
f[x][y] += dfs(a, b);
}
return f[x][y];
}
int main()
{
memset(f, -1, sizeof f);
f[3][4] = 1;
cout << dfs(0, 0) << endl;
return 0;
}
题解三
动态规划:
#include <iostream>
using namespace std;
int f[4][5];
int main()
{
for (int i = 1; i <= 4; i ++)
for (int j = 1; j <= 5; j ++)
{
if(i == 1 && j == 1) f[i][j] = 1; // 起点到起点只有一种方案
else if(i == 1) f[i][j] = 1; // 第一行只能从左边走过来
else if(j == 1) f[i][j] = 1; // 第一列只能从上面走下来
else f[i][j] = f[i - 1][j] + f[i][j - 1]; // 其余情况:每个格子都能由上面或左边走过来
}
cout << f[4][5] << endl;
return 0;
}