一開始我想,從上往下的話,可以用遞迴,搜尋(dfs)所有可能的路徑,**如下:
int dfs(int i,intj)
從第一層開始遞迴到最後一層再從最後一層往回遞迴,,一共遞迴2的n次方,顯然會t,那麼要怎麼優化一下呢?
我們看到,在題中第三排的1會被第二排的3和8遞迴兩次,經歷了一次重複計算,這時我們可以加入乙個判斷,使dp初始化為-1,如果判斷到dp[i][j]不等於-1,那麼這個數就是計算過的,不用再次重複遞迴了,具體**如下:
int dfs(int i,intj)
這樣就實現了「記憶化搜尋」,每乙個點只計算一次dp[i][j],那麼最終的複雜度就是n的平方。
for(int j=1;j<=n;j++)dp[n][j]=a[n][j];//
先計算最後一層
for(int i=n;i>=1;i--)
}
ac**:
#include#includeusing
namespace
std;
int dp[105][105
];int a[105][105
];int
main()
}for(int j=1;j<=n;j++)
dp[n][j]=a[n][j];
for(int i=n;i>=1;i--)
}printf(
"%d\n
",dp[1][1
]);
return0;
}
eof
記憶化搜尋 dp
例子 33 1132 3411 1先去找 1,1 的最長距離,很明顯為1 接著找 1,2 的最長距離,很明顯為1 接著找 1,3 的最長距離,為2 1,3 1 2 然後找 2,1 的最長距離,為2 2,1 1 1 然後是 2,2 的最長距離,如果沒有記憶化,那麼搜尋過程為 2,2 2 1 1 1 但...
遞迴方法 記憶化dp)
比如 w 30,1,0 w 30,1,0 既滿足條件1又滿足條件2 這種時候我們就按最上面的條件來算 所以答案為1 輸入測試樣例由多組測試資料組成。每組測試資料第一行輸入三個整數 a b c 20 a,b,c 20 如果a,b,c均為 1則退出程式 輸出輸出遞迴後的結果 樣例輸入 copy 1 1 ...
總結 遞迴 記憶化搜尋 遞迴
遞迴函式執行時分為函式 前進段和返回段,真正明白並時刻記住這個才真正掌握了遞迴。寫遞迴時三點 開始定義的 引數,結束條件 邊界 若干if語句 遞迴呼叫及 返回段運算 一般引數中總有乙個代表遞迴層數。遞迴結束返回時要考慮是否修改了全域性變數,並將其改回,這個是為回溯做準備。記憶化搜尋 解決了遞迴時大量...