【剑指】47.礼物的最大价值

题目描述

  • 在一个m×n的棋盘的每一格都放有一个礼物,每个礼物都有一定的价值(价值大于0)。你可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格直到到达棋盘的右下角。给定一个棋盘及其上面的礼物,请计算你最多能拿到多少价值的礼物?

算法分析

  • 动态规划,申请一个与原矩阵行列数一样的二维数组dp,然后依次更新dp的每一行即可。由于第m行的值与第m-1行和第m行有关,因此可以对dp进行简化,仅用一维数组即可完成状态的记录与更新。

提交代码:

class Solution {
public:
	/* 动态规划 */
	int getMaxValue_solution1(vector<vector<int> > values)
	{
		if (values.empty() || values[0].empty())
			return 0;

		int rows = values.size();
		int cols = values[0].size();
		// 反方向最大值
		int left, up;

		vector<vector<int> > maxVal(values);

		for (int i = 0; i < rows; ++i)
		{
			for (int j = 0; j < cols; ++j)
			{
				left = up = 0;
				if (j > 0)
					left = maxVal[i][j - 1];
				
				if (i > 0)
					up = maxVal[i - 1][j];

				maxVal[i][j] += (left >= up ? left : up);
			}
		}

		return maxVal[rows - 1][cols - 1];

	}

	/* 节约空间的做法 */
	int getMaxValue_solution2(vector<vector<int> > values)
	{
		if (values.empty() || values[0].empty())
			return 0;

		int rows = values.size();
		int cols = values[0].size();
		// 反方向最大值
		int left, up;
		vector<int> maxVal(cols, 0);

		for (int i = 0; i < rows; ++i)
		{
			for (int j = 0; j < cols; ++j)
			{
				left = up = 0;
				if (j > 0)
					left = maxVal[j - 1];

				if (i > 0)
					up = maxVal[j];

				maxVal[j] = (left >= up ? left : up) + values[i][j];
			}
		}

		return maxVal[cols - 1];
	}

};

测试代码:

// ====================测试代码====================
void test(const char* testName, vector<vector<int> > &values, int expected)
{
	Solution s;
	if (s.getMaxValue_solution1(values) == expected)
		cout << testName << ": solution passed." << endl;
	else
		cout << testName << ": solution FAILED." << endl;

	if (s.getMaxValue_solution2(values) == expected)
		cout << testName << ": solution passed." << endl;
	else
		cout << testName << ": solution FAILED." << endl;
}

void test1()
{
	// 三行三列
	vector<vector<int> > values = {
		{ 1, 2, 15 },
		{ 4, 5, 6 },
		{ 7, 8, 9 }
	};
	int expected = 33;
	test("test1", values, expected);
}

void test2()
{
	//四行四列
	vector<vector<int> > values = {
		{ 1, 10, 3, 8 },
		{ 12, 2, 9, 6 },
		{ 5, 7, 4, 11 },
		{ 3, 7, 16, 5 }
	};
	int expected = 53;
	test("test2", values, expected);
}

void test3()
{
	// 一行四列
	vector<vector<int> > values = {
		{ 1, 10, 3, 8 }
	};
	int expected = 22;
	test("test3", values, expected);
}

void test4()
{
	vector<vector<int> > values = {
		{ 1 },
		{ 12 },
		{ 5 },
		{ 3 }
	};
	int expected = 21;
	test("test4", values, expected);
}

void test5()
{
	// 一行一列
	vector<vector<int> > values = {
		{ 3 }
	};
	int expected = 3;
	test("test5", values, expected);
}

void test6()
{
	// 空指针
	int expected = 0;
	test("test6", vector<vector<int> >(), expected);
}

int main(int argc, char* argv[])
{
	test1();
	test2();
	test3();
	test4();
	test5();

	return 0;
}

猜你喜欢

转载自blog.csdn.net/ansizhong9191/article/details/81013702