47 礼物的最大值
题目
在一个 mxn 的棋盘中的每一个格都放一个礼物,每个礼物都有一定的价值(价值大于0).你可以从棋盘的左上角开始拿各种里的礼物,并每次向左或者向下移动一格,直到到达棋盘的右下角。给定一个棋盘及上面个的礼物,请计算你最多能拿走多少价值的礼物?
比如说现在有一个如下的棋盘:

在这个棋盘中,按照(1,12,5,7,7,16,5)的顺序可以拿到总价值最大的礼物。
C++ 题解
- 使用动态规划求解。
- 定义一个函数\(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)]+g(i,j);
\]
其中\(g(i,j)\)表示格子\((i,j)\)的礼物的价值。
- 设置一个和棋盘相同大小\(m×n\)的矩阵\(dp\),用来储存达到每个格子能拿到的礼物的最大值。
方法一
借助一个二维的数组:
int getMaxValue(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;
}
方法二
注意到计算每一格能拿到的礼物的最大值时,总是只使用了前一格和上面一格的值,所以理论上我们只需要维护一行数据即可,该行数据的长度为棋盘的列数n。
借助一个一维的数组:
int getMaxValue(const int* values, int rows, int cols)
{
if (values == nullptr || rows <= 0 || cols <= 0)
return 0;
int* maxValues = 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[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;
}
python 题解
方法一
借助一个二维的数组:
# -*- coding:utf-8 -*-
class Solution:
#假设输入array为一维数组,行数为rows,列数为cols,要求输出为最大的那个数值
def getMaxValue1(self,array,rows,cols):
# write code here
if array==[] or rows<=0 or cols<=0:
return 0
maxValues=[[0 for i in range(cols)] for j in range(rows)]
for i in range(rows):
for j in range(cols):
left=0
up=0
if i>0:
#如果行号大于0,说明它上面有数字
up=maxValues[i-1][j]
if j>0:
#如果列号大于0,说明它左边有数字
left=maxValues[i][j-1]
maxValues[i][j]=max(up,left)+array[i*cols+j]
return maxValues[rows-1][cols-1]
方法二
借助一个一维的数组:
# -*- coding:utf-8 -*-
class Solution:
#假设输入array为一维数组,行数为rows,列数为cols,要求输出为最大的那个数值
def getMaxValue2(self, array, rows, cols):
# write code here
if array == [] or rows <= 0 or cols <= 0:
return 0
maxValues=[0 for i in range(cols)]
for i in range(rows):
for j in range(cols):
up=0
left=0
if i>0:
#如果行号大于0,说明它上面有数字。up仍为当前列的maxValue
up=maxValues[j]
if j>0:
#如果列号大于0,说明它左边有数字。
left=maxValues[j-1]
maxValues[j]=max(up,left)+array[i*cols+j]
return maxValues[cols-1]

浙公网安备 33010602011771号