有關排列組合的一道算法題

有關排列組合的一道算法題

1、題目內容

廢話很少說,先上題目:javascript

有一個 n × m 的網格,左下角爲A,右上角爲B,規定每次只能走一步,而且方向只能是向上或者向右,求A到B共有多少種走法?(例如一個日字形的格子就是一個2 × 1的網格,共有3種走法)並用Javascript寫出程序算法。java

你們能夠先思考一下怎麼作,再去看個人方法。算法

2、解決方法

這個問題我想了好久,一直在走彎路,其實用一個抽象的數學方法就能夠很輕鬆解決這個問題。函數

如今你能夠把向右移動想象成記錄一個數字1,把向上移動抽象成記錄一個數字0,而且這些數字是按順序排列的。code

看到這裏我相信聰明的小夥伴已經想到了如何解決這個問題。ip

這個問題能夠抽象成n個0和m個1的不一樣排列的總數。好比2 × 2的網格就是2個0和2個1的全部不一樣排列的數量,也就是1100,1010,1001,0110,0101,0011。get

進而,咱們能夠把問題抽象成從(m + n)個0中,隨意抽取m個0並將它改成1的不一樣方法數,是否是以爲問題很熟悉,沒錯!就是高中的排列組合。我先把公式亮出來?:數學

C(m, n + m) = (n + m)!/(m! * n!)

想先複習一下排列組合知識的同窗能夠參見下一節。io

3、Javascript代碼描述

以上的結果用JS的描述,以下:function

function getMethods(n, m) {
  // 定義一個求階乘的輔助函數
  function factorial(x) {
    if (x === 0) {
      return 1
    } else {
      return factorial(x -1) * x
    }
  }
  return factorial(m + n)/(factorial(m) * factorial(n))
}

若是小夥伴有好的算法,能夠留言交流!

4、排列組合

簡單地講一下排列和組合。

排列

先舉個栗子(如下n,m均爲正整數),從n個含有標有不一樣數字小球的袋子裏,按順序抽取n個小球,且抽取後再也不放入袋子裏。第一次抽的時候,有n種可能;第二次抽的時候有n - 1種可能,以此類推,抽完n個小球總共的不一樣排列個數爲n!。

若是條件不變,只把抽取的小球個數改成m(m <= n)個,結果也就變成:

n × (n - 1) × (n - 2) × ... × (n - m + 1)
整理一下即:
A(m, n) = n! / (n - m)!

組合

一樣是n個標記不一樣數字的小球放入一個袋子中,也是抽取m個,可是此時不算抽取的順序。也就是把排列的結果n!/(n - m)!再除以m個小球隨機排列的總方法術,即m!,因此結果爲:

C(m, n) = A(m, n) / m! = n! / ( (n - m)! × m! )

如何得出以前的公式

運用以上的知識,能夠總結出如下公式:

C(m, n + m) = A(m, n + m) / m!

            = (n + m)! / ( n! × m! )
相關文章
相關標籤/搜索