遞迴的優化(動態規劃)

2021-08-22 14:51:37 字數 1898 閱讀 9656

使用遞迴方法來計算組合數:

從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...