1. 程式人生 > >《演算法設計與分析》第五週作業

《演算法設計與分析》第五週作業

《演算法設計與分析》第五週作業

標籤(空格分隔): 課堂作業

文章目錄

姓名:李**
學號: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;
    }
};