動態規劃(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的時候還是都不太會,我主要認為我只知道了動態規劃的基本思想,就是將乙個大的問題,分成若干個小問題,但與貪心演算法不同的是,動態規劃中的每乙個小問題之間都相互影響,在每一步都取得最優解,且在不斷...