面試題47:禮物的最大價值
題目:在乙個m×n的棋盤的每一格都放有乙個禮物,每個禮物都有一定的價值(價值大於0)。你可以從棋盤的左上角開始拿格仔裡的禮物,並每次向左或者向下移動一格直到到達棋盤的右下角。給定乙個棋盤及其上面的禮物,請計算你最多能拿到多少價值的禮物?
例如,在下面的棋盤中,如果沿著帶下劃線的數字的線路(1、12、5、7、7、16、5),那麼我們能拿到最大價值為53的禮物。
這是乙個典型的能用動態規劃解決的問題。我們先用遞迴的思路來分析。我們先定義第乙個函式 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]。gift[i, j]表示座標為(i, j)的格仔裡禮物的價值。
#include
#include
#include
#include
#include
#include
using
namespace std;
intgetmaxvalue_solution1
(const
int* values,
int rows,
int cols)
for(
int i=
0;iint maxvalue=maxvalues[rows-1]
[cols-1]
;for
(int i=
0;i)delete
maxvalues[i]
;delete
maxvalues;
return maxvalue;
}int
main()
;printf
("%d"
,getmaxvalue_solution1
(value,4,
4));
return0;
}
接下來我們考慮進一步的優化。前面我們提到,到達座標(i, j)的格仔時能夠拿到的禮物的最大價值只依賴(i-1, j)和(i, j-1)的兩個格仔,因此第 i-2 行及更上面的所有格仔禮物的最大價值實際上沒有必要儲存下來。我們可以用乙個一維陣列來替代前面**中的二維矩陣 maxvalue。該一維陣列的長度為棋盤的列數 n。當我們計算到達座標為(i, j)的格仔時能夠拿到的禮物的最大價值 f(i, j),陣列中前 j 個數字分別是 f(i, 0),f(i, 1),……,f(i, j-1),陣列從下標為 j 的數字開始到最後乙個數字,分別為 f(i-1, j),f(i-1, j+1),……,f(i-1, n-1)。也就是說,該陣列前面 j 個數字分別是當前第 i 行前面 j 個格仔禮物的最大價值,而之後的數字分別儲存前面第 i-1 行 n-j 個格仔禮物的最大價值。
#include
#include
#include
#include
#include
#include
using
namespace std;
intgetmaxvalue_solution2
(const
int* values,
int rows,
int cols)
}int maxvalue=maxvalues[cols-1]
;delete
maxvalues;
return maxvalue;
}int
main()
;printf
("%d"
,getmaxvalue_solution2
(value,4,
4));
return0;
}
劍指offer 面試題47 禮物的最大價值
問題 在乙個 m n 的棋盤的每一格都放有乙個禮物,每個禮物都有一定的價值 價值大於 0 你可以從棋盤的左上角開始拿格仔裡的禮物,並每次向右或者向下移動一格 直到到達棋盤的右下角。給定乙個棋盤及其上面的禮物的價值,請計算你最多能拿到多少價值的禮物。輸入 價值矩陣 輸出 最大價值 思路 動態規劃 定義...
劍指offer面試題7
面試題7 用兩個棧實現佇列 using namespace std template class cqueue 預備知識 佇列 佇列也是一種常見的資料結構 特點是先進先出 fifo 在stl中有stack和queue兩個容器 template class stack 成員函式 empty size ...
劍指offer面試題11
面試題1 數值的整數的次方 題目 實現函式double power double base,int exponent 求base的 exponent次方。不得使用庫函式,同時不需要考慮大數問題。思路 首先應該明確指數的可能取值 正整數,0,負整數 另外還需要考慮底數是0的情形。對於負整指數,我們可以...