【Java】 劍指offer(47) 禮物的最大價值


本文參考自《劍指offer》一書,代碼采用Java語言。

更多:《劍指Offer》Java實現合集  

題目 

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

思路

  動態規划:定義f(i,j)為到達(i,j)位置格子時能拿到的禮物總和的最大值,則有:f(i,j)=max{f(i,j),f(i,j)}+values(i,j)。

  同上道題一樣,如果直接使用遞歸會產生大量的重復計算,因此,創建輔助的數組來保存中間計算結果。

  輔助數組不用和m*n的二維數組一樣大,只需要保存上一層的最大值就可以。代碼中使用長度為列數n的一位數組作為輔助數組,注釋部分為二維輔助數組。

 

輔助數組只需要存 √ 的部分

測試算例 

  1.功能測試(多行多列,一行多列,多行一列,一行一列)

  2.特殊測試(null)

Java代碼

//題目:在一個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.這道題不用二維數組,只需要用一維數組作為輔助空間即可,以后遇到對中間結果的保存問題,看看能否優化輔助空間。

 

更多:《劍指Offer》Java實現合集  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM