《算法设计与分析》第五周作业

《算法设计与分析》第五周作业

标签(空格分隔): 课堂作业

姓名:李**
学号:16340114
题目:Unique Paths(https://leetcode.com/problems/unique-paths/description/)


前言

俗话说得好,有作业的假期就不能叫假期,要写算法博客的国庆还能叫国庆吗?
  国庆要回家,回家前先把博客给写(shui)了吧

题目概要

给定一个m*n的矩阵,一个机器人在左上角,目的地在右下角(点题目链接看图),机器人每次只能往下走或者往右走,问机器人走到终点有多少条独特的路径。

思路

其实这个很简单啊,机器人必须要向右走m-1次,向下走n-1次,进行简单的排列组合就可以得到答案的。总共要走(m + n - 2)次,在这(m + n - 2)次中,选择(m - 1)次向右走就可以,所以答案就是
   C m + n 2 m 2 C^{m-2}_{m+n-2}
  你以为这就结束了吗?这可是国庆特别版欸。我这么简单明了的算法肯定是可以打败100%的人啦。抱着好奇的心理去discussion里看了别人的答案,看完之后我的表情是这样的:
  在这里插入图片描述
  (图片来自网络)
  很多版本的答案都使用了递归,从目的地开始递归,计算当前的路径个数,一直用向左或者向上的走法进行bfs,递归回到起点,得到答案。不得不说这样的做法确实是很慢很麻烦(相比于我发现的偷鸡解法),但这不能否定这个思想是一个很重要的思想,可以在不能投机取巧的时候作为通用一个解题思路去解题。

具体实现

真做起来的时候发现 C m + n 2 m 2 C^{m-2}_{m+n-2} 还真是不好算,先算分子吧,会overflow;乘一个分子再除一个分母吧,又会发生精度误差(long double都救不回来)。还好这题的分子不大,直接算分子再算分母,最后相除就阔以了。

心得

学到老活到老。
  一门好课程应该在放假的时候把作业取消掉。

源码:

class Solution {
public:
    int uniquePaths(int m, int n) 
    {
        if (m < n)
            return uniquePaths(n, m);
        
        long double result = 1;
        int x = m - 1;
        int y = n - 1;
        int bound = y;
        int z = x + y;
        
        for (int i = 0; i < bound; i++)
        {
            result *= (long double)z;
            
            
            z--;
            
            
        }
        
         for (int i = 0; i < bound; i++)
        {
            result /= (long double)y;
            y--;
        }
        
        return (int)result;
    }
};

猜你喜欢

转载自blog.csdn.net/Ray0758/article/details/82904269
今日推荐