冪運算 陣列 快速冪運算在動態規劃中的應用

2021-10-14 16:46:14 字數 2556 閱讀 9810

我們知道動態規劃主要可以用來解決兩類問題:

優化問題

組合計數問題

花花今天就來和大家聊一聊在組合計數問題中,如何使用快速冪運算來進行加速,把時間複雜度從o(n)降低到o(logn)。用到的知識點有二進位制和矩陣運算。

狀態轉移方程:

dp[i][0] = dp[i - 1][0] * 3 + dp[i - 1][1] * 2

dp[i][1] = dp[i - 1][0] * 2 + dp[i - 1][1] * 2

邊界條件:

dp[1][0] = dp[1][1] = 6

求:dp[n][0] + dp[n][1]

對於這樣的轉移方程,我們一般使用遞推去求解,乙個for迴圈搞定。時間複雜度o(n),空間複雜度o(n),由於dp[i]只和dp[i-1]有關,可以進一步使用滾動陣列/臨時變數來降維,把空間複雜度降低到o(1)。

很多同學以為線性的遞推就是最快的了,其實不然。遞推雖然實現簡單,也能通過所有測試樣例,但並不是最優的。我們還可以做的更好,只需要把狀態轉移方程改寫成矩陣形式即可:

我們可以直接寫出dp[n]和dp[1]的關係:

這樣問題就變成如何快速求解常數矩陣的n次冪。

我們今天就來介紹一種快速整數冪運算的方法:平方法

一般形式為 x = a*b^n,底數b可以是實數也可以是矩陣,n必須是正整數。我們從b開始,每次把b平方,就能得到b^(2^k)。在這個過程中,把n看成乙個二進位制數,如果第k位為1,表示最終結果需要乘以b^(2^k),否則就跳過。

我們以x = 2 * 3^43為例,43的二進位制為:0b101011,第2位和第4位位0,也就是要跳過3^(2^2) = 3^4 和 3^(2^4) = 3^16,我們得到:

快速冪運算的偽**如下:

note1:如果a,b為矩陣,則把乘法的部分換成矩陣相乘即可。

note2:由於結果會非常大,通常每一步計算後都需要進行取餘操作。

很明顯時間複雜度是o(logn),因為n的二進位制長度為o(logn),迴圈會執行o(logn)次,迴圈內所有的操作都是o(1),所以總的時間複雜度是o(logn)。

回到我們之前說的1411題,dp[n] = dp[0] * m^(n-1) 

c++**如下,其中mul是最簡單的矩陣相乘的實現。

我們再來看另外乙個例子:leetcode 935. knight dialer,這次的係數矩陣很大,10x10,但之後的**是一樣的。

這兩題的dp[i]只和dp[i-1]有關,改寫成矩陣形式比較簡單。我們再來看兩個稍微複雜一些的例子。

leetcode 70. climbing stairs 這道題就是讓你求斐波那契數列的第n項。

轉移方程:dp[i] = dp[i-1] + dp[i-2]

邊界條件:dp[0] = dp[1] = 1

同樣我們可以把它改寫成矩陣形式,需要構造乙個2x2的矩陣

其中dp[-1] = 0

後面的計算部分是一樣的,最後我們的答案就儲存在dp[0][0]。

note:這題不需要取餘。

最後乙個例子是 790. domino and tromino tiling

狀態轉移方程比較複雜:

f[i] = f[i-1] + f[i-2] + 2 * g[i-1]

g[i] = f[i-2] + g[i-1]

邊界條件:

f[0] = f[1] = 1, g[0] = g[1] = 0

求:f[n]

我們依舊可以把它改寫成矩陣形式,變數矩陣是1x3,係數矩陣是3x3:

可以得到:

寫了這麼多,相信大家對快速冪運算以及其在動態規劃中的應用有了一定的了解,不要求掌握,感興趣的同學可以去自己推導和實現一下。

快速冪運算

知識點 快速冪運算 快速冪運算 原來 當我們計算a k時候,一定是 a a a a a k個 現在 把k拆成二進位制,為了表達清楚,我們這裡讓k 11 11 dec 1011 b 1 2 3 0 2 2 1 2 1 1 2 0 我們會發現其中有0的地方是個廢操作 那麼我們將去除這個廢操作的過程叫做快...

快速冪運算

如果我們要求x n次方 當n很大的時候 會gg 這個時候就會用到快速冪演算法了,顧名思義,快速冪,快速求冪。因為任何乙個數都可以用2進製表示。比如9 2 3 2 0 7 2 2 2 1 2 0 所以我們可以把n看成 n 2 k1 2 k2 2 k3.這樣來表示。當然我們同樣可以把x用這樣表示。即 x...

快速冪運算

首先,快速冪的目的就是做到快速求冪,假設我們要求a b,按照樸素演算法就是把a連乘b次,這樣一來時間複雜度是o b 也即是o n 級別,快速冪能做到o logn 快了好多好多。它的原理如下 假設我們要求a b,那麼其實b是可以拆成二進位制的,該二進位制數第i位的權為2 i 1 例如當b 11時 a1...