通過最近對於一些演算法題的思考,越來越發現動態規劃方法的在時間上高效性,往往該問題可以輕鬆的找到暴力破解的方法,其時間複雜度卻不盡人意。下面來看看幾個常見的動態規劃思路的經典問題
f(n):表示n階樓梯有多少種走法
f(n)=f(n−1)+f(n−2)
f(1)=1,f(2)=2
例二:01揹包問題
有n個重量和價值分別為vector weight, vector value的物品;揹包最大負重為w,求能用揹包裝下的物品的最大價值?
輸入:n =4
weight=2, 1, 3, 2
value =3, 2, 4, 2
w=5
輸出=7
dp[i][j]表示前i號物品中能選出重量在j之內的最大價值
dp[i][j]=max(dp[i−1][j],dp[i−1][j−w[i]]+v[i]);
例三:最大連續子串行和
如給定陣列[-2,1,-3,4,-1,2,1,-5,4]
連續的子陣列為[4,-1,2,1]有最大和6
f(j+1)為以下標j結尾的連續子串行和的最大值
f(j+1)=max(f(j)+a[j],a[j])
target=maxf[j]
思考:最大連續子串行乘積
如給定陣列[-2,1,-3,4,-1,2,1,-5,4]
連續的子陣列為[4,-1,2,1]有最大和6
f(j+1)為以下標j結尾的連續子串行最大乘積值(1)
狀態轉移方程如何表示呢:
這裡我們知道a[j]可能為正數(或0)或負數,那麼當a[j]為正數,期望前j個乘積為正數,若為負數,則期望前面的為負數。故我們需定義兩個函式來確定我們的狀態轉移方程:
fmax(j+1)=max(max(fmax(j)∗a[j],a[j]),fmin(j)∗a[j])
fmin(j+1)=min(min(fmin(j)∗a[j],a[j]),fmax(j)∗a[j])(2)
1.通過以上動態問題問題的分析,可以看出最重要的是定義好相應的問題,然後寫出狀態轉移方程,往往這也是整個問題求解最能考察你分析能力的過程。能夠用動態規劃求解的問題有兩類性質:
a.重疊子問題
採用遞推方式,比如上例要求出10階樓梯走法,那麼最後一步是踏一步上來或者踏2步上來,最後轉化為相應的子問題,子問題深入求解就包含了重疊的子問題,所以自頂向下的實現並不高效,常採用備忘錄方式儲存子問題的最優解,自底向上更高效。
b.最優子結構:
往往子問題的最優解可以推出原問題的最優解
LeetCode 動態規劃 n個骰子的點數
把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,列印出s的所有可能的值出現的概率。你需要用乙個浮點數陣列返回答案,其中第 i 個元素代表這 n 個骰子所能擲出的點數集合中第 i 小的那個的概率。示例 輸入 1 輸出 0.16667,0.16667,0.16667,0.16667,0.16...
運籌學狀態轉移方程例子 動態規劃簡單例子
遊艇租用問題 實驗目的和內容 實驗目的 1 能用程式語言實現求解相關問題的演算法 2 深刻掌握動態規劃法的設計思想並能熟練運用 3 理解這樣乙個觀點 同樣的問題可以用不同的方法解決,乙個好的演算法是反覆 努力和重新修正的結果。實驗內容 長江遊艇俱樂部在長江上設定了n個遊艇出租站1,2,n。遊客可在這...
乙個簡單的動態規劃題
一直感覺 動態 規劃和排列好難的 乙個簡單的題目。開司,乙個整日遊手好閒 無所事事 混跡人生 軟弱無能 放縱慾望 毫無進取 嗯,實在是太多了,就不一一枚舉了。總之,他就是完美的符合了我們日常中對人渣這一詞的認識。不過他有這唯一,也是無敵般的特長,就是逆境求生 不論是什麼樣的逆境,他都可以翻盤。這不是...