当前位置:   article > 正文

走方格&&跳格子(dp,递归,排列组合三种方法)_跳格子算法

跳格子算法

走方格:

给定一个 n×mn×m 的方格阵,沿着方格的边线走,从左上角 (0,0)(0,0) 开始,每次只能往右或者往下走一个单位距离,问走到右下角 (n,m)(n,m) 一共有多少种不同的走法。

输入格式

共一行,包含两个整数 nn 和 mm。

输出格式

共一行,包含一个整数,表示走法数量。

数据范围

1≤n,m≤101≤n,m≤10

输入样例:

2 3

输出样例:

10

方法一:dp动态规划,定义一个二维数组a[12][12],当跳到a[i][j]时,该方案数总是由两部分组成,

一部分是跳到a[i-1][j]的方案数,另一部分是跳到a[i][j-1]的方案数,即a[i][j]=a[i-1][j]+a[i][j-1],特别的,当i==0||j==0时,方案只有一种,即a[i][j]=1

  1. #include <iostream>
  2. using namespace std;
  3. int m,n;
  4. int main()
  5. {
  6. cin>>m>>n;
  7. int a[12][12]={0};
  8. for(int i=0;i<=m;i++)
  9. for(int j=0;j<=n;j++)
  10. if(i==0||j==0)
  11. a[i][j]=1;
  12. else
  13. a[i][j]=a[i-1][j]+a[i][j-1];
  14. cout<<a[m][n]<<endl;
  15. return 0;
  16. }

方案二:递归,先列出样例所有方案数的情况,符合dfs深度优先搜索

每次搜索中

若搜到了点 (n,m),那么 cnt++
否则如果不是最右边的点,那么搜该点右边的点
如果不是最下面的点,那么搜该点下面的点

  1. #include <iostream>
  2. using namespace std;
  3. int m,n,cnt=0;
  4. void dfs(int a,int b)
  5. {
  6. if(a==m&&b==n) cnt++;
  7. if(a<m) dfs(a+1,b);
  8. if(b<n) dfs(a,b+1);
  9. }
  10. int main()
  11. {
  12. cin>>m>>n;
  13. dfs(0,0);
  14. cout<<cnt<<endl;
  15. return 0;
  16. }

方案三:排列组合,每次都是走n+m步,然后从中选出n步向下.fenzi和fenmu数字可能会特别大,int会爆,所以用longlong

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n,m;
  6. long long fenzi=1,fenmu=1;
  7. cin>>n>>m;
  8. for(int i=1;i<=n+m;i++)
  9. { if(i>n)
  10. fenzi=fenzi*i;
  11. if(i<=m)
  12. fenmu=fenmu*i;
  13. }
  14. // cout<<fenzi<<' '<<fenmu<<endl;
  15. cout<<fenzi/fenmu<<endl;
  16. return 0;
  17. }

跳格子:

一个楼梯共有 nn 级台阶,每次可以走一级或者两级,问从第 00 级台阶走到第 nn 级台阶一共有多少种方案。

输入格式

共一行,包含一个整数 nn。

输出格式

共一行,包含一个整数,表示方案数。

数据范围

1≤n≤151≤n≤15

输入样例:

5

输出样例:

8

方案一:f[i]代表跳到第i级台阶的方案数

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int f[20],n;
  6. cin>>n;
  7. f[1]=1,f[2]=2;
  8. for(int i=3;i<=n;i++)
  9. f[i]=f[i-1]+f[i-2];
  10. cout<<f[n]<<endl;
  11. return 0;
  12. }

方案2:

  1. #include<iostream>
  2. using namespace std;
  3. int n,cnt=0;
  4. void dfs(int a)
  5. {
  6. if(a==n) cnt++;
  7. else if(a<n) //一定要有这个条件,要不然退出不了dfs
  8. {
  9. dfs(a+1);
  10. dfs(a+2);
  11. }
  12. }
  13. int main()
  14. {
  15. cin>>n;
  16. dfs(0);
  17. cout<<cnt<<endl;
  18. return 0;
  19. }

方案三:以样例为例,方案由1 1 1 1 1,

1112,1121,1211,2111,

221,212,122,

每一种单独的方案符合排列组合问题,n个台阶,每一种方案最少有(n+1)/2个数,最多有n个数

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n,cnt=1,res=0,up=1,down=1; //res代表有几个2
  6. cin>>n;
  7. int a=(n+1)/2; //向上取整
  8. while (n --&&n>=a)
  9. {
  10. up=1,down=1;
  11. res++;
  12. for(int i=n;i>n-res;i--) up=up*i;
  13. for(int i=1;i<=res;i++) down=down*i;
  14. cnt=cnt+up/down;
  15. }
  16. cout<<cnt<<endl;
  17. return 0;
  18. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/208961
推荐阅读
相关标签
  

闽ICP备14008679号