最近又看到一篇文章,說到算法對前端的重要性,遂抽出時間(玩的時間),逼着本身看一些相關的知識,當看到動態規劃相關文獻時,也勾起了很大的興趣,學習各位大神的博客,有了初步理解,藉此記載,可能比較淺顯,對於一樣初學相關知識的同窗,或許會有幫助,若有問題,望大神指出前端
學習的最好方法即是帶着問題學習,因此首先先採用網上廣泛的、對理解動態規劃很友好的一個問題做爲學習切入點,問題解決後再總結概括算法
如今有10級臺階,每次只能上1級或2級臺階,問:到達10級臺階的方法有多少?學習
首先按照正常邏輯,看到這個問題或許會懵,由於狀況太多無從下手,可是最優解每每須要更改思考方式優化
function methods(n) { if (n == 1) return 1 if (n == 2) return 2 console.log('計算') return methods(n - 1) + methods(n - 2) } console.log(methods(10)); // 89
問題到這看似已經解決了,可是我想同窗在思惟導圖中應該也發現了,不少子問題是重複的,可是上面代碼卻作了不少重複工做,很浪費 冗餘(以下圖),咱們但願已經計算過的就不要在重複計算spa
因此優化下, 保存計算過的結果:code
var resultList = [] // 保存計算過的結果,以計算的臺階數作索引下標 function methods(n) { if (n == 1) return 1 if (n == 2) return 2 if (!resultList[n]) { // 沒有就保存 console.log('計算', n) resultList[n] = methods(n - 1) + methods(n - 2) } return resultList[num] }
這樣看,就節省了不少計算,臺階總數越大,越明顯
而後我們再精簡下代碼:遞歸
var resultList = [0, 1, 2]; // 對於本題的結果預存了,方便點 function fnSumF(n) { if (!resultList[n]) resultList[n] = fnSumF(n - 1) + fnSumF(n - 2); return resultList[n] }
動態規劃的英文名是Dynamic Programming,是一種分階段求解決策問題的數學思想;與分治方法相似,都是經過組合子問題的解來來求解原問題的。再來了解一下什麼是分治方法,以及這二者之間的差異,分治方法將問題劃分爲互不相交的子問題,遞歸的求解子問題,再將它們的解組合起來,求出原問題的解。而動態規劃與之相反,動態規劃應用與子問題重疊的狀況,即不一樣的子問題具備公共的子子問題(子問題的求解是遞歸進行的,將其劃分爲更小的子子問題)。在這種狀況下,分治方法會作許多沒必要要的工做,他會反覆求解那些公共子子問題。而動態規劃對於每個子子問題只求解一次,將其解保存在一個表格裏面,從而無需每次求解一個子子問題時都從新計算,避免了沒必要要的計算工做。索引
其實關於和分治的區別,在咱們解決問題優化時已經能夠看出ip
初學的淺層理解,若有問題但願你們指出,指點,若是問題或者好文章,也但願能夠評論推薦博客
學的越多,才發現本身懂得越少