1. 程式人生 > >【LeetCode & 劍指offer刷題】動態規劃與貪婪法題7:47:禮物的最大價值

【LeetCode & 劍指offer刷題】動態規劃與貪婪法題7:47:禮物的最大價值

【LeetCode & 劍指offer 刷題筆記】目錄(持續更新中...)

47:禮物的最大價值

題目:

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

解答:

1. 利用迴圈的動態規劃實現,使用輔助二維陣列

定義f(i,j)表示到達座標為(i,j)的格子時能拿到的禮物總和的最大值; 有兩種路徑到達(i,j):(i-1,j)或者(i,j-1);
f(i,j) = max(f(i-1,j), f(i,j-1)) + gift[i,j]; 使用迴圈來計算避免重複子問題。   class Solution { public :     int getMaxValue_solution ( const int * values , int
rows , int cols ) {         if ( values == nullptr || rows <= 0 || cols <= 0 )            
return 0 ;           int** maxValues = new int*[rows]; //開闢一個矩陣儲存每個座標點的禮物最大值         for ( int i = 0 ; i < rows ; ++ i )             maxValues [ i ] = 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 = maxValues [ i - 1 ][ j ];                 if ( j > 0 )                     left = maxValues [ i ][ j - 1 ];                 maxValues [i][j] = std::max(left, up) + values[i*cols + j];             }         }         int maxValue = maxValues [ rows - 1 ][ cols - 1 ];         for ( int i = 0 ; i < rows ; ++ i )             delete [] maxValues [ i ];         delete [] maxValues ;         return maxValue ;     } };

2. 優化空間複雜度,使用一維陣列

題目中可知,座標(i,j)的最大禮物價值僅僅取決於座標為(i-1,j)和(i,j-1)兩個格子; 因此第i-2行以上的最大價值沒有必要儲存下來。 使用一維陣列儲存:(0,0)…(0,j-1)儲存的是(i,0)…(i,j-1)的最大價值;(0,j)…(0,cols-1)儲存的是(i-1,j)…(i-1,cols-1)的最大價值。 每次計算新的(i,j)時,使用陣列下標j-1和j的最大值加當前禮物值即可。  
               
               
               
        (i,j)      
               
    class Solution { public :     int getMaxValue_solution ( const int * values , int rows , int cols ) {         if ( values == nullptr || rows <= 0 || cols <= 0 )             return 0 ;         int* maxValues = new int[cols]; //開闢一個一維陣列即可,a[i][j]上的最大值存與maxValues[j]中         for ( int i = 0 ; i < rows ; ++ i ) {             for ( int j = 0 ; j < cols ; ++ j ) {                 int left = 0 ;                 int up = 0 ;                 if ( i > 0 )                     up = maxValues[j];                 if ( j > 0 )                     left = maxValues[j - 1];                 maxValues [ j ] = std :: max ( left , up ) + values [ i * cols + j ];             }         }         int maxValue = maxValues[cols - 1];         delete [] maxValues ;         return maxValue ;     } };