题目:
第一步:举例探索
- 2*2 ->2
* - 3*3 ->6
* *
(1.2)
(1.3) *
(2.1)
*
(2.2)
(3.1)
- 4*4 ->20
##黄色方格为在上一个表格的基础上多出来需要走的方格,*方格为有俩条路可走的方格* *
(1.2)
*
(1.3)
(1.4) *
(2.1)
* *
(2.3)
(2.4)
*
(3.1)
* *
(3*3)
分析:
每次只统计黄色方格 向下 和 向右 俩种“岔路口”的可能情况
3*3
3*3在2*2表格基础上增加了从 黄色方格 (1.2) (2.1)进入红色方格 和 白色方格(1.3)(3.1)进入红色方格 的几种路经
向下:(1.2)向下的路径及进入2*2方格,有2种路径
向右:(1.2)向右的路径及进入1*3方格,只有1种路径
同时不难发现:(1.2)(1.3)和(2.1)(3.1)对称,路径相同
4*4
4*4同样只增加了黄色方格的路径,与3*3不同的是,进入的方格不再是n*n型,而是n*m型
向下:(1.2)向下及进入3*3方格,没有区别
(1.3)向下及进入了2*3的表格,处于“分岔口”,再拆解 向下:及进入 2*2 方格,2种
向右:及进入 1*3 方格,1种
向右:(1.2)向右及是(1.3)向下 向右 俩种情况之和
(1.3)向右及进入1*4方格,1种
不难发现:只要方格为1*n型,就只有一种路径,对于不规则n*m型可拆解为n*n型和1*n型,逐层拆解,即可想到递归。
第二步:验证
根据图像列出:每次“岔路口”向右和向下进入的方格
3*3 = 3*2 + 2*3 = 3*1 + 2*2 + 2*2 + 1*3 = 3*1 + 2*1 + 1*2 + 1*2 + 2*1 + 1*3 = 6 结果正确
向右 向下 向右 向下 向右 向下 向右 向下 向右 向下
4*4 = @#¥%……&*(
第三步:代码实现
#include <stdio.h>
int re(int a,int b){
if(a<=1||b<=1){
return 1;
}else{
return (re(a-1,b)+re(a,b-1));
}
}
int main(){
int n,m;
int sum;
scanf("%d %d",&m,&n);
sum=re(m,n);
printf("%d",sum);
return 0;
}
第四步:总结
对于小数据而言没有问题,但是有时结果数量很多,超出了int存储最大范围,使用递归,就算使用 Mod 10^9+7输出结果,仍然会超时。所以需再次优化。
第五步:优化
改变思路,寻找规律,标记到达每个方格的路径个数
1 | 1 | 1 | 1 | 1 |
1 | 2 | 3 | 4 | 5 |
1 | 3 | 6 | 10 | 15 |
1 | 4 | 10 | 20 | 35 |
1 | 5 | 15 | 35 | 70 |
显而易见......到达每个方格的路径,是到达上面和左面方格路径之和
#include <cstdio>
#define mod 1000000007
int array[1000][1000];
int main() {
int n, m ;
scanf("%d %d", &m, &n);
for (int i = 0 ; i < m ; i++) {
array[0][i] = 1 ;
}
for (int i = 0 ; i < n ; i++) {
array[i][0] = 1 ;
}
for (int i = 1 ; i < n ; i++) {
for (int j = 1 ; j < m ; j++) {
array[i][j] = (array[i - 1][j] + array[i][j - 1] ) % mod ;
}
}
printf("%d\n", array[n - 1][m - 1]) ;
return 0 ;
}
Over!
如果对你有帮助,点个赞留下你的声影。