HJ91 题解 | #走方格的方案数#

走方格的方案数

http://www.nowcoder.com/practice/e2a22f0305eb4f2f9846e7d644dba09b

HJ91 题解 | #走方格的方案数#

题意分析

  • 一个很经典的题目,给出一个二维矩阵,从左上角走到右下角,每次只能往右走或者往下走,问我们有多少种走的方案?

思路分析

解法一 动态规划

  • 我们发现,假设我们某一个时刻走到了位置(i,j)(i,j),那么,我们如何求到达这个位置的情况的数目呢?

alt

  • 所以我们可以很容易得到状态转移方程,dp[i][j]=dp[i1][j]+dp[i][j1]dp[i][j]=dp[i-1][j]+dp[i][j-1]

  • 代码如下

    • 二维循环,先进行行的遍历,再进行列的遍历,更新每个位置的状态。时间复杂度为O(nm)O(nm)
    • 需要存储每个位置的状态,空间复杂度为O(nm)O(nm)
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N=20;
ll dp[N][N];
int main(){
    int n,m;
    while(cin>>n>>m){
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=n;i++){
            for(int j=0;j<=m;j++){
                // 如果是初始的位置
                if(i==0&j==0){
                    dp[i][j]=1;
                    continue;
                }
                // 如果是第一行,那么直接从左边转移过来
                if(i==0){
                    dp[i][j]=dp[i][j-1];
                    continue;
                }
                // 如果是第一列,那么直接从上面转移过来
                if(j==0){
                    dp[i][j]=dp[i-1][j];
                    continue;
                }
                // 否则,可以从上面和左边转移过来
                dp[i][j]=dp[i-1][j]+dp[i][j-1];
            }
        }
        cout<<dp[n][m]<<endl;
    }
}

解法二 数学排列组合

  • 我们发现,我们走的步数是固定的,对于每走一步,我们只能有两个选择,要么向右边,要么向下边,而且,我们发现,我们向右和向下的步数是固定的,所以我们就可以将题目转化为在一共n+m步中,选择其中的n步往下走的情况的数目,或者说选择m步往右走的情况的数目。这样,就是一个很显然的数学排列组合题目了。

  • 代码如下

    • 最坏的循环的次数为n+m,所以总的时间复杂度为O(n+m)O(n+m)
    • 只开了少数几个变量,空间复杂度为O(1)O(1)
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
int main(){
    int n,m;
    while(cin>>n>>m){
        ll up=1,down=1;
        // 计算(m+n)!/m!
        for(int i=n+m;i>m;i--){
            up=up*i;
        }
        // 计算n!
        for(int i=n;i;i--){
            down=down*i;
        }

        ll ans=up/down;
        cout<<ans<<endl;
    }
}
全部评论

相关推荐

程序员小白条:你是沟通了900个,不是投了900份简历,你能投900份,意味着对面都要回复你900次,你早就找到实习了,没亮点就是这样的,别局限地区,时间投的也要早,现在都要7月了
点赞 评论 收藏
分享
06-13 17:33
门头沟学院 Java
顺序不记了,大致顺序是这样的,有的相同知识点写分开了1.基本数据类型2.基本数据类型和包装类型的区别3.==和equals区别4.ArrayList与LinkedList区别5.hashmap底层原理,put操作时会发生什么6.说出几种树型数据结构7.B树和B+树区别8.jvm加载类机制9.线程池核心参数10.创建线程池的几种方式11.callable与runnable区别12.线程池怎么回收线程13.redis三剑客14.布隆过滤器原理,不要背八股,说说真正使用时遇到了问题没有(我说没有,不知道该怎么回答了)15.堆的内存结构16.自己在写项目时有没有遇见过oom,如何处理,不要背八股,根据真实经验,我说不会17.redis死锁怎么办,watchdog机制如何发现是否锁过期18.如何避免redis红锁19.一个表性别与年龄如何加索引20.自己的项目的QPS怎么测的,有没有真正遇到大数量表21.说一说泛型22.springboot自动装配原理23.springmvc与springboot区别24.aop使用过嘛?动态代理与静态代理区别25.spring循环依赖怎么解决26.你说用过es,es如何分片,怎么存的数据,1000万条数据怎么写入库中27.你说用limit,那么在数据量大之后,如何优化28.rabbitmq如何批次发送,批量读取,答了延迟队列和线程池,都不对29.计网知不知道smtp协议,不知道写了对不对,完全听懵了30.springcloud知道嘛?只是了解反问1.做什么的?短信服务,信息量能到千万级2.对我的建议,基础不错,但是不要只背八股,多去实际开发中理解。面试官人不错,虽然没露脸,但是中间会引导我回答问题,不会的也只是说对我要求没那么高。面完问我在济宁生活有没有困难,最快什么时候到,让人事给我聊薪资了。下午人事打电话,问我27届的会不会跑路,还在想办法如何使我不跑路,不想扣我薪资等。之后我再联系吧,还挺想去的😭,我真不跑路哥😢附一张河科大幽默大专图,科大就是大专罢了
查看30道真题和解析
点赞 评论 收藏
分享
评论
1
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务