劍指Offer之禮物的最大價值

題目描述:

在一個 m*n 的棋盤的每一格都放有一個禮物,每個禮物都有一定的價值(價值大於 0)。你可以從棋盤的左上角開始拿格子裏的禮物,並每次向右或者向下移動一格、直到到達棋盤的右下角。給定一個棋盤及其上面的禮物的價值,請計算你最多能拿到多少價值的禮物?

題目分析:

此類題目做的多了,思路就比較清晰了。下面用例子來說明:

設棋盤如下:(grid[]來表示棋盤:3 x 3)

【1, 3, 1】
【1, 5, 1】
【4, 2, 1】

現在來分析:

設置一個數組res[][],記錄走過路線上的最大值。如果從grid[0][0]走到grid[0][2]:

在res[0][0]時,最大值爲res[0][0] = grid[0][0] = 1;

res[0][0] -> res[0][1]時,最大值爲res[0][1] = res[0][0] + grid[0][1] = 1 + 3 = 4;

res[0][1] -> res[0][2]時,最大值爲res[0][2] = res[0][1] + grid[0][2] = 4 + 1 = 5;

同理:從grid[0][0]到grid[2][0]也類似;

下來分析出了第一行和第一列的最大值:

可以看出:res[1][1] = grid[1][1] + max(res[1][0], res[0][1]);


思路分析:

設置res[][],先分別求出走第1行和第1列時每個位置的最大值;然後計算出其它行的最大值,其他行的最大值等於
res[i][j] = grid[i][j] + max(res[i][j - 1], res[j - 1][i]);

在這裏插入圖片描述

參考代碼:

這裏直接給出一維數組的解法。

public int maxValue(int[][] grid) {
   if(grid == null || grid.length == 0)return 0;
   int m = grid.length;
   int n = grid[0].length;
   int[] dp = new int[n];
   dp[0] = grid[0][0];
   for(int i = 1; i < n; i++){
      dp[i] = dp[i - 1] + grid[0][i];
   }
   for(int i = 1; i < m; i++){
      for(int j = 0; j < n; j++){
         if(j == 0)dp[j] = dp[j] + grid[i][j];
         else dp[j] = grid[i][j] + Math.max(dp[j - 1], dp[j]);
      }
   }
   return dp[n - 1];
}

(完)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章