2017-05-24 55 views
0

我正在嘗試使遞歸函數的動態函數,我有點卡住了。遞歸動態函數

遞歸:

static int F(int m, int n) 
    { 
     if(n == 0) 
      return m; 

     if (m == 0 && n > 0) 
      return n; 

     else 
      return Math.Min((1 + F(m - 1, n)), Math.Min((1 + F(m, n - 1)), (D(m-1, n-1) + F(m - 1, n - 1)))); 
    } 

    static int D(int i, int j) 
    { 
     Console.WriteLine("i:{0} | j:{1}", i, j); 
     if (x[i] == y[j]) 
     { 
      return 1; 
     } 
     return 0; 
    } 

動態(所有我至今):

static int F2(int m, int n) 
    { 
     if (n == 0) 
     { 
      return m; 
     } 
     if(m==0 && n > 0) 
     { 
      return n; 
     } 
     else 
     { 
      //Math.Min((1 + F(m - 1, n)), Math.Min((1 + F(m, n - 1)), (D(m-1, n-1) + F(m - 1, n - 1)))); 
     } 
    } 

,問題是有人可以給我解釋一下我怎麼轉換這個Math.Min((1 + F(m - 1, n)), Math.Min((1 + F(m, n - 1)), (D(m-1, n-1) + F(m - 1, n - 1))));代碼到動態?我對遞歸有點新。

+0

DP算法的主要複雜性是弄清楚如何定義一個單元的方式。你已經做到了。除此之外,它看起來幾乎與任何其他DP算法相同。我真的很努力地看到你想與哪一部分轉換 - 這一切都非常簡單。 – Dukeling

回答

1

在動態編程方法中,您可以使用二維查找表,您可以使用這種方式填寫所有需要的數據。

既然你遞歸mn取決於F(m - 1, n)F(m, n - 1)F(m - 1, n - 1),所有你需要做的是確保當你開始計算F(m, n)這些值已經計算。例如:

static int F2(int M, int N) { 
    var F = new int[M + 1, N + 1]; 

    for (var m = 0; m <= M; m++) { 
     for (var n = 0; n <= N; n++) { 
      if (n == 0) { 
       F[m, n] = m; 
       continue; 
      } 
      if (m == 0 && n > 0) { 
       F[m, n] = n; 
       continue; 
      } 
      F[m, n] = Math.Min((1 + F[m - 1, n]), Math.Min((1 + F[m, n - 1]), (D(m-1, n-1) + F[m - 1, n - 1]))); 
     } 
    } 

    return F[M, N]; 
} 

我選擇了名稱,以便查看它如何映射到遞歸方法。

+0

非常感謝!這真的很有幫助。 :)我試過你的代碼,並且出現錯誤。 – David

+0

@David,我的壞,我改變<<<=在循環 –

+0

它現在的作品。但我不確定爲什麼我會得到錯誤的答案。 – David