題目描述:
在一個 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];
}
(完)