9.1數字三角形

9.1.1問題描述與狀態定義

回溯法過於麻煩,爲了得到高效的算法,需要用抽象的方法思考問題:把當前的位置(i,j)看出一個狀態,然後定義狀態(i,j)的指標函數d(i,j)爲從格子(i,j)發出時能得到的最大和(包括格子(i,j)本身的值)。在這個狀態定義下,原問題的解是d(1,1)

狀態轉移方程

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

9.1.2記憶化搜索與遞歸

方法一:遞歸計算

int solve(int i,int j){
    return a[i][j]+(i==n?0: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]);
時間複雜度爲 N*N;

方法3:記憶化搜索

程序分成兩個部分,首先用“memset(d,-1,sizeof(d));” 把d全部初始化爲-1,然後編寫遞歸函數

int solve(int i,j){
    if(d[i][j]>=0)
        return d[i][j];
    return d[i][j]=a[i][j]+(i==n?0:max(solve(i+1,j),solve(i+1,j+1)))
}




發佈了38 篇原創文章 · 獲贊 2 · 訪問量 8033
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章