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

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

動態規劃之數字三角形

2019-11-11 03:34:07
字體:
來源:轉載
供稿:網友

數字三角形 

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

                   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]中。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 台北市| 延长县| 房山区| 和林格尔县| 古丈县| 集贤县| 延长县| 连云港市| 衡阳市| 巫山县| 东兴市| 肇州县| 张北县| 溧水县| 清流县| 荆门市| 临安市| 青川县| 鹤岗市| 长沙县| 彭山县| 晴隆县| 七台河市| 湘潭市| 清丰县| 沂南县| 巧家县| 准格尔旗| 遂平县| 莱西市| 黄浦区| 陆良县| 郧西县| 泰和县| 临沧市| 建水县| 开化县| 嘉义县| 灵川县| 游戏| 泰州市|