給定兩個字串x和y,將x變成y所須要改變的字符的個數是多少?期間能夠的操做是:bash
字串能夠是非連續的。它等效於找兩個字符串的最大公共字串,好比 HIEROGLYPHOLOGY 和 MICHAELANGELO 最大公共字串爲 HELLOspa
數量爲:
指針
DP(i,j)=min(cost of replace X[i] to Y[j]+ DP(i+1,j+1),cost of delete X[i]+DP(i+1,j),cost of insert Y[j]+DP(i,j+1) )
子問題的耗時:O(1)code
for i in 0,...,|x|:
for j in 0,...,|y|:
複製代碼
原始的問題:DP(0,0),總的時間爲:O(1)*O(|x||y|)cdn
假設有以下形式的矩陣作乘法 blog
最終總會是兩個矩陣相乘,那這兩個矩陣是怎麼計算獲得的?假設有一次區分,那麼它是().(
)這種樣子,左邊括號中也會繼續按照這種方式劃分,同理右邊也須要,當左右兩邊都須要相似計算的時候,這種時候一般就是取substring排序
子問題的個數爲
。每次選擇至關於1分爲2字符串
執行應該是(
).(
)這種樣子 有的選擇的數量:O(n)。去嘗試全部的可能string
須要分別計算左邊括號的部分和右邊括號的部分,以及最後計算出來的左右兩個部分的乘積it
DP(i,i+1)=0
子問題的時間:O(n)。D(i,k)的計算忽略不計,只有k的選擇存在循環
總時間消耗:
給定一個詞的集合words,使用badness(i,j)表示使用的單詞是words[i,j]
目標就是使得分出來的詞展現在各個行,使得最小
很差看的展現以下
blah blah blah b l a h verylongworld 複製代碼
但願它能展現成
blah blah blah blah verylongworld 複製代碼
一個個的去嘗試全部單詞的劃分,也就是說,去判斷任意一個詞,是否應該在它的位置換行,若是有n個單詞的話,總共須要嘗試的次數是
按照標準的動態規劃步驟來進行:
假設找到了第一行的分隔點,那麼接下來須要考慮的是第二行又該在哪兒開始換行呢?依次繼續往下去查找,因此須要思考的子問題就是去掉第一行的詞以後,剩下的那些單詞
子問題的數量:n。只有n個單詞,後綴的次數也就是這些
猜想的選擇的數量:<=n-i=O(n)。每次選完了第一行,只須要在剩下的單詞裏面選
DP[i]=min(badness(i,j)+DP[j] for j in range(i+1,n+1))
定義問題爲求DP(i)的最小值。當i=n的時候,是沒有單詞剩下的,花銷是0。
假設第一次在第i個位置開始換行,第一行的計算髮方式爲 badness(i,j),剩下的須要解決的問題部分是從i+1開始的單詞,也就是剩下部分的花銷假設從j開始,它可能取得剩下部分的任意值,每一個j的取值所須要的花銷就是D(j),那麼這兩部分相加最小時,也就是最優的劃分方式
循環部分耗時(每一個子問題耗時):O(n)。j總共有n種選擇,加法部分是常量
須要先從最末端開始計算,再一層層的網上去累加 時間爲:問題的數量*每一個問題的花銷=
使用一個指針parent來代表j中的最小值是那個,那麼沿着parent指針,0->parent[0]->parent[parent[0]]一直到最後,便可獲得最佳的劃分方式
有一個吉他,在彈的時候,能夠用任何一個手指來談,那麼若是給予一系列的音符notes,每一個音符都須要用手(手指頭取值 1,..,F)處理,每一個手指去某個音符彈後須要移到另外一個音符用一個手指去彈,假設描述這種移動使用d(p,f,q,g)表示花銷,那如何去使得花銷最小?
d(p,f,q,g):表示手指f移動到g,彈的音符從p到q
通常思考是:
正確思路爲:
i表示note[i]的音符
for i in reversed(range(n)): //全部的音符
for f in 1...F: //每一個手指頭都有可能來彈音符
複製代碼
最終去解決原始問題,DP(0,f),可是須要指定f,因此使用 min(DP(0,f) for f in 1,...,F),即初始的時候應該選擇那一個手指去談第一個音符
這種場景便是要考慮更多的狀況,來達到最優解