【劍指 Offer 題解】47. 禮物的最大價值

題目

在一個 m*n 的棋盤的每一個格都放有一個禮物,每個禮物都有一定價值(大於 0)。從左上角開始拿禮物,每次向右或向下移動一格,直到右下角結束。給定一個棋盤,求拿到禮物的最大價值。例如,對於如下棋盤

示例

Input:
1    10   3    8
12   2    9    6
5    7    4    11
3    7    16   5

Output:
53
禮物的最大價值爲 1+12+5+7+7+16+5=53

思路

  • dp[i][j] 表示到達棋盤上(i,j)位置上禮物的最大值,。
  • dp[i][j] = max(dp[i-1][j], dp[i][j-1]) + values[i][j]
  • 初始值:
  • (1)dp[0][0] = values[0][0]
  • (2)拿第一行(第一列)的禮物,每次向右(向下)移動一格
public int getMost(int[][] values) {
	int n = values.length;
	int m = values[0].length;
	int[][] dp = new int[n][m];
	dp[0][0] = values[0][0];
	for (int i = 1; i < n; i++) {
		dp[i][0] = dp[i-1][0] + values[i][0];
	}
	for (int j = 1; j < m; j++) {
		dp[0][j] = dp[0][j-1] + values[0][j];
	}
	
	for (int i = 1; i < n; i++) {
		for (int j = 1; j < m; j++) {
			dp[i][j] = Math.max(dp[i-1][j], dp[i][j-1]) + values[i][j];
		}
	}
	return dp[n-1][m-1];
}

優化

  • 計算每一格禮物最大值,只使用到前一格和上一格的值,所以理論上我們只需要維護一行數據即可,該行數據的長度爲棋盤的列數m。
public int getMost(int[][] values) {
    if (values == null || values.length == 0 || values[0].length == 0)
        return 0;
    int m = values[0].length;
    int[] dp = new int[m];
    for (int i = 0; i < values.length; i++) {
    	dp[0] += values[i][0];
    	for (int j = 1; j < m; j++) {
			dp[j] = Math.max(dp[j], dp[j - 1]) + values[i][j];
		}
    }
    /*
    for (int[] value : values) {
        dp[0] += value[0];
        for (int i = 1; i < m; i++)
            dp[i] = Math.max(dp[i], dp[i - 1]) + value[i];
    }
    */
    return dp[m - 1];
}

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