本文參考自《劍指offer》一書,代碼採用Java語言。html
更多:《劍指Offer》Java實現合集 java
在一個m×n的棋盤的每一格都放有一個禮物,每一個禮物都有必定的價值(價值大於0)。你能夠從棋盤的左上角開始拿格子裏的禮物,並每次向左或者向下移動一格直到到達棋盤的右下角。給定一個棋盤及其上面的禮物,請計算你最多能拿到多少價值的禮物?數組
動態規劃:定義f(i,j)爲到達(i,j)位置格子時能拿到的禮物總和的最大值,則有:f(i,j)=max{f(i,j),f(i,j)}+values(i,j)。post
同上道題同樣,若是直接使用遞歸會產生大量的重複計算,所以,建立輔助的數組來保存中間計算結果。測試
輔助數組不用和m*n的二維數組同樣大,只須要保存上一層的最大值就能夠。代碼中使用長度爲列數n的一位數組做爲輔助數組,註釋部分爲二維輔助數組。優化
輔助數組只須要存 √ 的部分url
測試算例 spa
1.功能測試(多行多列,一行多列,多行一列,一行一列)htm
2.特殊測試(null)blog
//題目:在一個m×n的棋盤的每一格都放有一個禮物,每一個禮物都有必定的價值 //(價值大於0)。你能夠從棋盤的左上角開始拿格子裏的禮物,並每次向左或 //者向下移動一格直到到達棋盤的右下角。給定一個棋盤及其上面的禮物,請計 //算你最多能拿到多少價值的禮物? public class MaxValueOfGifts { public int maxValueOfGifts(int[][] values) { if(values==null || values.length<=0 ||values[0].length<=0) return 0; int rows=values.length; int cols=values[0].length; // int[][] maxValue=new int[rows][cols]; int[] maxValue=new int[cols]; for(int i=0;i<rows;i++) { for(int j=0;j<cols;j++) { int left=0; int up=0; if(i>0) // up=maxValue[i-1][j]; up=maxValue[j]; if(j>0) // left=maxValue[i][j-1]; left=maxValue[j-1]; // maxValue[i][j]=Math.max(up, left)+values[i][j]; maxValue[j]=Math.max(up, left)+values[i][j]; } } // return maxValue[rows-1][cols-1]; return maxValue[cols-1]; } }
1.動態規劃問題,用公式來表示清楚。
2.動態規劃若是有大量重複計算,能夠用循環+輔助空間來提升效率。
2.這道題不用二維數組,只須要用一維數組做爲輔助空間便可,之後遇到對中間結果的保存問題,看看可否優化輔助空間。