動態規劃一(一般動態規劃)

2021-10-05 14:51:52 字數 2231 閱讀 4602

動態規劃(dynamic programming,dp)是一種用來解決一類最優化問題的演算法思想。將乙個複雜的問題分解為若干個子問題,通過綜合子問題的最優解來得到原問題的最優解。動態規劃會將每個求解過的子問題的解都記錄下來(dp陣列),這樣當下一次遇到的時候就可以直接使用,而不用重複計算。

乙個問題必須擁有重疊子問題和最優子結構,才能使用動態規劃去解決。

(最優子結構:乙個問題的最優解可以由其子問題的最優解有效地構造出來)

舉例:dp[i][j] = max(dp[i+1][j],dp[i+1][j+1]) + f[i][j]

其中dp[i][j] 稱為問題的狀態,上面的式子稱為狀態轉移方程。而對於dp陣列初始化的部分,稱為邊界

問題描述

如果乙個自然數n的k進製表示中任意的相鄰的兩位都不是相鄰的數字,那麼我們就說這個數是k好數。求l位k進製數中k好數的數目。例如k = 4,l = 2的時候,所有k好數為11、13、20、22、30、31、33 共7個。由於這個數目很大,請你輸出它對1000000007取模後的值。

輸入格式

輸入包含兩個正整數,k和l。(1 <= k,l <= 100。)

輸出格式

輸出乙個整數,表示答案對1000000007取模後的值。

樣例輸入

4 2樣例輸出

7以數的位數為行,以最前位的數字為列(k進製的可選數字為0,1,2,…,k-1)

構建二維dp陣列

dp[i][j] 表示 i 位數以 j 開頭的數字個數

假設k=4,l=2 進行填表

已知任意的一位數字,不管以什麼開頭都只有一種

0 , 1, 2, 3

填表中的第一行:

當數字長度為2位的時候,由於00,01,02,03均不構成數字

因此填寫第二行

2+2+3 = 7 答案為7種

所以狀態轉移方程為:

dp[i][j] = dp[i][j] + dp[i-1][x]

x為遍歷0~k-1的數字中,不和前一位的數字j相鄰的數字

如:dp[2][1] = dp[2][1]+ ( dp[1][1]+dp[1][3] )

python:

k,l =

map(

int,

input()

.split())

#k進製 l位數

ans =[[

0for j in

range

(k)]

for i in

range

(l+1)]

#dp陣列

cnt =

0for i in

range

(k):

#初始化

ans[1]

[i]=

1for i in

range(2

,l+1):

for j in

range

(k):

for x in

range

(k):

#遍歷0~k-1的數字

if x != j-

1and x != j+1:

#不與j相鄰

ans[i]

[j]+= ans[i-1]

[x] ans[i]

[j]%=

1000000007

for i in

range(1

,k):

#將第l行的所有個數相加即為總個數

cnt += ans[l]

[i] cnt %=

1000000007

print

(cnt)

動態規劃 一

在現實生活中,有一類活動的過程,由於它的特殊性,可將過程分程若干個互相聯絡的階段,在它的每一階段都需要作出決策,從而使整個過程達到最好的活動效果。當然,各個階段決策的選取不是任意確定的,它依賴於當前面臨的狀態,又印象以後的發展,當各個階段決策確定後,就組成乙個決策序列,因而也就確定了整個過程的一條活...

動態規劃(一)

動態規劃的兩種常用形式 1 遞迴型 在函式中呼叫自身 優點 直觀,容易編寫 缺點 可能會因為遞迴層數太深導致爆棧,函式呼叫帶來額外時間開銷。無法使用滾動陣列節省空間。總體來說,比遞推型慢。2 遞推型 for迴圈 效率高,有可能使用滾動陣列節省空間。有的問題只能用遞迴解決,有的問題既可以用遞迴,也可以...

動態規劃 (一)

對於動態規劃的學習總共進行了兩節課,到現在為止還是一頭霧水,雖然看懂了老師上課講的例題,但是做v judge的時候還是都不太會,我主要認為我只知道了動態規劃的基本思想,就是將乙個大的問題,分成若干個小問題,但與貪心演算法不同的是,動態規劃中的每乙個小問題之間都相互影響,在每一步都取得最優解,且在不斷...