dp的基本思想,是把大問題轉化成乙個個小問題,然後遞迴解決。
所以本質思想的話還是遞迴。
dp最重要的是要找到狀態轉移方程,也就是把大問題化解的過程。
舉個例子
乙個數字金字塔
1122332
2243
133
在上面的數字三角形中尋找一條從頂部到底邊的路徑,使得路徑上所經過的數字之和最大。路徑上的每一步都只能往左下或 右下走。只需要求出這個最大和即可,不必給出具體路徑。 三角形的行數大於1小於等於100,數字為 0 - 99.
這個題不難想到,你只要找出每一步的最大值就可以。·
那麼這麼找呢?(遞迴啊~)
我們先看看狀態轉移方程
/*首先,肯定得用二維陣列來存放數字三角形
然後我們用d( r, j) 來表示第r行第 j 個數字(r,j從1開始算)
我們用maxsum(r, j)表示從d(r,j)到底邊的各條路徑中,最佳路徑的數字之和。
因此,此題的最終問題就變成了求 maxsum(1,1)
當我們看到這個題目的時候,首先想到的就是可以用簡單的遞迴來解題:
*/if ( r ==n)
maxsum(r,j) =d(r,j)
else
maxsum( r, j) = max + d(r,j)
那麼是不是就可以了?
1 #include 2 #include 3#define max 101
4using
namespace
std;
5int
d[max][max];
6int
n;
7int maxsum(int i, int
j)
14int
main()
但實際上,這個**會超時的。
為什麼呢,
因為已經走過的路,存在重複遍歷了
那就把已經遍歷過的做一下標記,就可以避免重複遍歷了。
1 #include 2 #include 3using
namespace
std; 45
#define max 101 67
intd[max][max];
8int
n;
9int
maxsum[max][max];
1011
int maxsum(int i, int
j)
21return
maxsum[i][j];
22}
23int
main()
31 cout << maxsum(1,1) <32 }
動態規劃入門 DP基礎
1,include using namespace std int main int solve int i,int j int main float p,pj,q,qj int n,mj float dp 5000 int main dp 0 1 for int i 1 i n i for int...
動態規劃入門
1 用 dp 做的題大多數返回值是int boolean,求max min,不能打亂原來輸入順序。2 動態規劃有兩個重要定義,乙個叫 optimal substructure 另乙個叫 overlap subproblem 各種排序 tree 類問題中,都會用到 divide conquer 的思想...
動態規劃入門
大家可以看看這篇文章dp,哪個更容易理解就看哪個!一 動態規劃的定義 動態規劃程式設計是一種針對於解決最優化問題的一種途徑 一種方法,而不是一種特殊演算法,也就是說它沒有固定的模板。在動態規劃中,每走一步都要看看能不能最優,而且動態規劃最擅長的就是多階段問題!二 動態規劃的基本概和基本模型構成 1....