leetcode-741. 摘樱桃

首先介绍一下贪心的思路,每次都取最优解。对于第一条路径来说,记录一下最优路径,接着将最优路径上的樱桃重置为0. 然后再利用一次贪心的思路。当然贪心思想是错误的

int func(vector>& grid, vector>& dp)
{

	int m = grid.size();
	int n = grid[0].size();
	

	int sum = grid[0][0];
	dp[0][0] = sum;
	for (int i = 1; i < n; i++)
	{
		sum += grid[0][i];
		if (grid[0][i] == -1)dp[0][i] = -1;
		else
			dp[0][i] = dp[0][i - 1] == -1 ? -1 : sum;
	}


	sum = grid[0][0];
	for (int i = 1; i < m; i++)
	{
		sum += grid[i][0];
		if (grid[i][0] == -1)dp[i][0] = -1;
		else
			dp[i][0] = dp[i - 1][0] == -1 ? -1 : sum;
	}

	for (int i = 1; i < m; i++)
	{
		for (int j = 1; j < n; j++)
		{
			if (grid[i][j] == -1){
				dp[i][j] = -1;
				continue;
			}

			if (dp[i - 1][j] == -1 && dp[i][j - 1] == -1)
			{
				dp[i][j] = -1;
			}
			else if (dp[i - 1][j] != -1 && dp[i][j - 1] == -1)
			{
				dp[i][j] = dp[i - 1][j] + grid[i][j];
			}
			else if (dp[i - 1][j] == -1 && dp[i][j - 1] != -1)
			{
				dp[i][j] = dp[i][j - 1] + grid[i][j];
			}
			else if (dp[i - 1][j] != -1 && dp[i][j - 1] != -1)
			{
				dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]) + grid[i][j];
			}
		}
	}

	return dp[m - 1][n - 1];
}



int cherryPickup(vector>& grid) {
	int m = grid.size();
	int n = grid[0].size();
	vector> dp(m, vector(n, INT_MIN));


	int res1 = func(grid,dp);
	if (res1 == -1)return -1;

	vector> coor;
	int i = m - 1;
	int j = n - 1;
	coor.push_back({ i, j });

	while (i >= 1 && j >= 1)
	{
		if (dp[i - 1][j] != -1 && dp[i][j - 1] == -1)
		{
			i--;
			coor.push_back({ i, j });
		}
		else if (dp[i - 1][j] == -1 && dp[i][j - 1] != -1)
		{
			j--;
			coor.push_back({ i, j });
		}
		else if (dp[i - 1][j] != -1 && dp[i][j - 1] != -1)
		{
			if (dp[i][j - 1] > dp[i - 1][j])
			{
				j--;
				coor.push_back({ i, j });
			}
			else{
				i--;
				coor.push_back({ i, j });
			}
		}
	}

	if (i == 0 && j == 0)coor.push_back({ 0, 0 });
	while (i != 0 || j != 0)
	{
		if (i == 0){
			j--;
			coor.push_back({ 0, j });
		}
		else if(j==0){
			i--;
			coor.push_back({ i, 0 });
		}
	}

	for (int i = 0; i < coor.size(); i++)
	{
		auto e = coor[i];
		//cout << "(" << e[0] << "," << e[1] << ")" << endl;
		grid[e[0]][e[1]] = 0;
	}

	vector> dp2(m, vector(n, INT_MIN));
	int res2 = func(grid, dp2);


	return res1+res2;
}

找一个反例,这个例子所有的樱桃都可以得到。

leetcode-741. 摘樱桃_第1张图片

 以下是正确的做法:同时维护两条路径就行了。

int cherryPickup1(vector>& grid)
{
	int n = grid.size();

	int step = 2 * n - 1;
	vector>> dp(step, 
		vector>(n, vector(n, INT_MIN)));

	dp[0][0][0] = grid[0][0];

	for (int s = 0; s < step-1; s++)
	{
		for (int x1 = 0; x1 = 0 && x1 < n && y1 + 1 >= 0 && y1 + 1 < n) &&
					(x2 >= 0 && x2 < n && y2 + 1 >= 0 && y2 + 1 < n) &&
					grid[x1][y1 + 1] != -1 && grid[x2][y2 + 1] != -1)
				{
					if (x1 == x2)dp[s + 1][x1][x2] = max(dp[s + 1][x1][x2], 
														dp[s][x1][x2] + grid[x1][y1 + 1]);
					else
						dp[s + 1][x1][x2] = max(dp[s + 1][x1][x2],
												dp[s][x1][x2] + grid[x1][y1 + 1] + grid[x2][y2 + 1]);
				}

				//右侧,下侧
				if ((x1 >= 0 && x1 < n && y1 + 1 >= 0 && y1 + 1 < n) &&
					(x2+1 >= 0 && x2+1 < n && y2>= 0 && y2< n) &&
					grid[x1][y1 + 1] != -1 && grid[x2+1][y2] != -1)
				{
					if (x1 == x2 + 1)dp[s + 1][x1][x2 + 1] = max(dp[s + 1][x1][x2 + 1],
																dp[s][x1][x2] + grid[x1][y1 + 1]);
					else
						dp[s + 1][x1][x2 + 1] = max(dp[s + 1][x1][x2 + 1],
													dp[s][x1][x2] + grid[x1][y1 + 1] + grid[x2 + 1][y2]);
				}

				//下侧,右侧

				if ((x1+1 >= 0 && x1+1 < n && y1 >= 0 && y1 < n) &&
					(x2>= 0 && x2 < n && y2+1 >= 0 && y2+1< n) &&
					grid[x1+1][y1] != -1 && grid[x2][y2+1] != -1)
				{
					if (x1 + 1 == x2)dp[s + 1][x1 + 1][x2] = max(dp[s + 1][x1 + 1][x2] ,
																dp[s][x1][x2] + grid[x1 + 1][y1]);
					else
						dp[s + 1][x1 + 1][x2] = max(dp[s + 1][x1 + 1][x2], 
													dp[s][x1][x2] + grid[x1 + 1][y1] + grid[x2][y2 + 1]);
				}


				//下侧,下侧

				if ((x1+1 >= 0 && x1+1 < n && y1>= 0 && y1 < n) &&
					(x2 + 1 >= 0 && x2 + 1 < n && y2 >= 0 && y2< n) &&
					grid[x1+1][y1] != -1 && grid[x2 + 1][y2] != -1)
				{
					if (x1 == x2)dp[s + 1][x1 + 1][x2 + 1] = max(dp[s + 1][x1 + 1][x2 + 1],
															dp[s][x1][x2] + grid[x1 + 1][y1]);
					else
						dp[s + 1][x1 + 1][x2 + 1] = max(dp[s + 1][x1 + 1][x2 + 1], 
														dp[s][x1][x2] + grid[x1 + 1][y1] + grid[x2 + 1][y2]);
				}
			}
		}
	}



	return dp[step - 1][n - 1][n - 1] == INT_MIN ? 0 : dp[step - 1][n - 1][n - 1];

}

你可能感兴趣的:(数据结构,leetcode,贪心算法,算法)