国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

動態規劃之數字三角形

2019-11-11 04:50:09
字體:
來源:轉載
供稿:網友

數字三角形 

有一個由非負整數組成的三角形,第一行只有一個數,除了最下行之外每個數的左下方和右下方各有一個數。

                   1

                2     3

           4       5       6

     7         8      9        10

從第一行數開始,每次可以往左下或右下走一格,直到走到最下行,把沿途經過的數全部加起來。如何才能使得這個和盡量大?

一個n層數字三角形的完整路線有2^(n-1)條,當n很大時再一個個去求會很麻煩,為了得到高效的算法,需要用抽象的方法思考問題:把當前的位置(i,j)看做一個狀態,然后定義狀態(i,j)的指標函數d(i,j)為從格子(i,j)出發時能得到的最大和(包括(i,j)本身的值),在這個狀態定義下,原問題的解是d(0,0)。

于是得到狀態轉移方程

d(i,j)=a(i.j)+max{d(i+1,j),d(i+1,j+1)}

動態規劃的核心是狀態和狀態轉移方程。

記憶化搜索和遞推

方法一:遞歸計算

int solve(int i,int j)

{

    return  a[i][j] + (i==n ? : max( solve(i+1,j),solve(i+1,j+1) );

}

這樣做是正確的,但是時間效率太低,其原因在于重復計算。

方法二:遞推計算。

int i , j;

for(j = 1;j <= n;j++) d[n][j] = a[n][j];

for(i = n-1;i >= 1;i--)

     for(j =1 ;j<=i;j++)

          d[i][j] = a[i][j]+ max(d[i+1][j],d[i+1][j+1]);

程序的時間復雜度為 O(n^2),但為什么可以這樣計算呢?,原因在于i是逆序枚舉的,在計算d[i][j]時它所需要的d[i+1][j],d[i+1][j+1]已經計算出來了。

方法三:記憶化搜索。

程序分為兩部分,首先用“memset”把d全部初始化為-1,然后編寫遞歸函數:

int solve(int i,int j)

{

      if(d[i][j]>=0)   return d[i][j];

return a[i][j] + (i==n ? : max( solve(i+1,j),solve(i+1,j+1) );

上述程序依然是遞歸的,但同時也把計算結果保存在數組d中。題目中說各個數都是肺腑的,因此如果已經計算過某個d[i][j],則它應是非負的。這樣,只需要把所有d初始化為-1,即可通過判斷是否d[i][j]>=0得知它是否已經被計算過。最后把它保存在d[i][j]中。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 连南| 丰县| 白朗县| 如皋市| 安吉县| 桐乡市| 瓮安县| 潢川县| 兴和县| 湘乡市| 泾源县| 涿州市| 互助| 多伦县| 开阳县| 宜州市| 阳江市| 丰都县| 凤台县| 旬阳县| 邻水| 六安市| 富源县| 武平县| 鄂托克旗| 尖扎县| 汉寿县| 辉县市| 大丰市| 浦县| 成武县| 全南县| 夏邑县| 仙桃市| 新民市| 津南区| 孙吴县| 全州县| 普宁市| 宝鸡市| 山东|