使用遞迴方法來計算組合數:
從m個不同元素中,任取n(n≤m)個元素並成一組,叫做從m個不同元素中取出n個元素的乙個組合;從m個不同元素中取出n(n≤m)個元素的所有組合的個數,叫做從m個不同元素中取出n個元素的組合數。
公 式: c(m,n)=n!/((m-n)!*n!)(n≤m)
性 質:c(m,n)= c(m,m-n) --可以推導出--》 c(m,0) = c(m,m) = 1
c(m,n)=c(m-1,n-1)+c(m-1,n)
請使用遞迴的方法來計算組合數。
使用遞迴的方法去解決,**如下:
用遞迴方法雖然會很容易的去解決,但在計算過程中卻多出了很多不必要的計算,例如:當我們來計算c(6,4)時,我們需要計算c(5,3)和c(5,4),而計算c(5,3)又要計算c(4,2)和c(4,3),依次 類推。
我們考慮:這裡有很多中間結果被反覆計算,從而引起了時間和空間上(遞迴需要分配棧空間)的浪費,
所以我們可以考慮將計算的中間結果記錄在某處,然後當再次需要這個結果時,從已經計算的結果中來查詢,從而得到結果,
這樣在時間上可以節省大量的成本,當然,空間上則需要一定輔助空間。
我們發現這裡有大量的重複預算。這也就是為什麼遞迴在時間和空間(遞迴要開闢棧空間)上有大量的資源消耗。因此在這裡我們就要採用另一種解決方案,那就是使用動態規劃來優化演算法。
按照這個思路,我們嘗試用一張大的表來有序的儲存中間結果。
如下圖,我們讓行對應m,讓列對應n,這樣我們根據c(m,0) = c(m,m) = 1,可以將下標中
的黑色區域填上初始值1;
然後根據性質:c(i,j)=c(i-1,j-1)+c(i-1,j)
我們找到了計算出c(i,j)的方法,所以在計算c(5,2)
時可以使用c(4,1)+c(4,2)=4+6=10
**如下:
import numpy as np
def dyproject(n,m):
if m>=n:
return 1
myarray = np.ones((n+1,m+1), dtype=np.int16)
t=n-m
for i in range(1,t+1):
for r in range(1,m+1):
myarray[r+i][r] = myarray[r+i-1][r-1]+myarray[r+i-1][r]
return myarray[n][m]
n = int(input("請輸入n的值:"))
m = int(input("請輸入m的值:"))
t=dyproject(n,m)
print('%d個元素取%d個元素的組合數為:'%(n,m),t)
輸出如下
我們用乙個矩陣的分布形式來表示n、m之間的關係c(m,n)=c(m-1,n-1)+c(m-1,n),n是他的橫座標m是他的縱座標,那麼c(8,3)=c(7,2)+c(7,3)=c[7][3]+c[7][2],以此類推可得出c(8,3)=56
動態規劃 遞迴
動態規劃是求解包含重疊子問題的最優化方法 1.基本思想 將原問題分解為相似的子問題,在求解的過程中通過子問題的解求出原問題的解 注意 不是簡單分而治之 2.只能應用於有最優子結構的問題 即區域性最優解能決定全域性最優解,或問題能分解成子問題來求解 3.具有無後效性。它要求每乙個問題的決策,不能夠對解...
遞迴 動態規劃 POJ Help Jimmy
1 3 8 17 20 0 10 8 0 10 13 4 14 3 首先明確遞迴函式的功能 由於向左走和向右走是性質一樣的兩個子問題,因此此時遞迴函式的就是針對當前平板的向左 右走,計算時間 遞迴結束條件 當遞迴到第n個平板時,遞迴結束,返回當前高度 當前高度小於限定的最高高度 確定遞迴的等價關係 ...
動態規劃與遞迴
這裡借用leetcode的一道例題,來說一下動態規劃和遞迴的區別 給定乙個三角形,找出自頂向下的最小路徑和。每一步只能移動到下一行中相鄰的結點上。相鄰的結點 在這裡指的是 下標 與 上一層結點下標 相同或者等於 上一層結點下標 1 的兩個結點。例如,給定三角形 2 3,4 6,5,7 4,1,8,3...