標籤:style blog color io os for 資料 sp div
問題描述
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
給出了一個數字三角形。從三角形的頂部到底部有很多條不同的路徑。對於每條路
徑,把路徑上面的數加起來可以得到一個和,和最大的路徑稱為最佳路徑。你的任務就是求
出最佳路徑上的數字之和。
注意:路徑上的每一步只能從一個數走到下一層上和它最近的左邊的數或者右邊的數。
輸入資料
輸入的第一行是一個整數 N (1 < N <= 100),給出三角形的行數。下面的 N行給出數字
三角形。數字三角形上的數的範圍都在 0和 100之間。
我們形象的描述下這個問題,把每一層的數字,描述為金子數量,那麼我們就是要選擇一條最優的路徑,獲得最大的金子數量。
思路:從第0層到最後4層來遞迴,當我在第0層,思考往左還是往右的時候,實際上這就是一個選擇,類似0,1背包的放還是不放。那麼第一層的最優解=往左走的最優解和往右走的最優解中的最大值+第0層的金子,那麼這裡也就產生了兩個最優子結構,所以可以得出狀態轉移方程:f(i,j)=max(f(i+1,j),f(i+1,j+1))+Tri[i][j]
1 #include <iostream> 2 using namespace std; 3 int mydp[5][5]; 4 int Tri[5][5]={{7}, 5 {3,8}, 6 {8,1,0}, 7 {2,7,4,4}, 8 {4,5,2,6,5}}; 9 int get_max37(int a,int b)10 {11 return a>b?a:b;12 }13 int max_sum(int i,int j)14 {15 int retMax;16 if(mydp[i][j]!=-1)17 {18 retMax=mydp[i][j];19 }20 //邊界條件21 else if(i==4)22 {23 retMax=Tri[i][j];24 }25 else26 {27 retMax=get_max37(max_sum(i+1,j),max_sum(i+1,j+1))+Tri[i][j];28 }29 mydp[i][j]=retMax;30 return retMax;31 }32 int main() 33 {34 for (int i=0;i<5;++i)35 {36 for (int j=0;j<5;++j)37 {38 mydp[i][j]=-1;39 }40 }41 cout<<max_sum(0,0);42 system("pause");43 return 0;44 }
動態規劃習題:數字三角形