【動態規劃】數字三角形最大值(一)(遞迴)
阿新 • • 發佈:2019-01-03
題目:數字三角形,形如
3
3 2
4 5 1
1 3 4 1
每個點只能選擇向左或向右走,取一條路徑,使得路徑上數字和最大。
無需求出路徑,求出最大值。
輸入n,和 n 行數字三角形 n<=100
思路:遞迴解決
用二維陣列 d[ l ][ r ] 存數字三角形
if ( l == n) maxSum( l , r ) = d [ l ][ r ] ;
else maxSum ( l , r ) = max { maxSum( l+1, r ) , maxSum( l+1, r+1 ) }
很簡單呀
程式碼如下:
#include <iostream> #include <algorithm> using namespace std; #define MAX 101 int d[MAX][MAX]; int n; int MaxSum(int l,int r) { if(l==n) return d[l][r]; else return max(MaxSum(l+1,r),MaxSum(l+1,r+1))+d[l][r]; } int main() { cin >> n; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) cin >> d[i][j]; cout << MaxSum(1,1) << endl; return 0; }
好了,資料量大一點的時候,就華麗麗的超時了
分析一下時間複雜度,發現是 O(2^n),原因是
會 重 復 計 算 maxSum (r,l) 的值!
————————————————————————————————————————————————————————————————————————————
優化:(記憶遞迴型動態規劃)
思路:那就把計算結果存下來嘛。
程式碼如下:
#include <iostream> #include <algorithm> using namespace std; #define MAX 101 int d[MAX][MAX]; int n; int maxSum[MAX][MAX]; int MaxSum(int i,int j) { if(maxSum[i][j]!=-1) return maxSum[i][j]; if(i==n) maxSum[i][j] = d[i][j]; else maxSum[i][j] = max(MaxSum(i+1,j),MaxSum(i+1,j+1)) + d[i][j]; return maxSum[i][j]; } int main() { cin >> n; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++){ cin >> d[i][j]; maxSum[i][j]=-1; } cout << MaxSum(1,1) << endl; return 0; }
演算法時間複雜度成功變成 O(n^2);
不過遞迴還是慢一點,繼續優化!