【LeetCode】64. 最小路径和(动态规划--中等)

64. 最小路径和

题目链接

在这里插入图片描述
dp思想:
dp[i][j]表示从右上角走到(i, j)这个位置后,路径上的数字总和为最小dp[i][j]
初始化 dp[0][0] = grid[0][0]
dp[i][0] = grid[i][0] + dp[i-1][0];
dp[0][i] = grid[0][i] + dp[0][i-1];
递推关系式: dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + arr[i][j]

#include<iostream>
#include<vector>
using namespace std;

/**
说个题外话,写到这里突然想到了
vector<vector<int> > grid1 和vector<int> grid2[ArraySize]
有什么区别来着?
答案就是: 虽然 grid1和grid2都是二维数组, 
但是grid1是两个维度 都是可变长的, 
而grid2只有第二个维度是可变长的, 第一个维度是固定不变的, 即ArraySize。 
*/

//dp思想
//dp[i][j]表示从右上角走到(i, j)这个位置后,路径上的数字总和为最小dp[i][j] 
//初始化 dp[0][0] = grid[0][0]
//dp[i][0] = grid[i][0] + dp[i-1][0];
//dp[0][i] = grid[0][i] + dp[0][i-1];
//递推关系式:dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + arr[i][j]
int minPathSum(vector<vector<int> > &grid) 
{
	const int rowLen = grid.size();
	const int colLen = grid[0].size();
	int dp[rowLen][colLen]={0};
	dp[0][0] = grid[0][0];
	for(int i=1;i<rowLen;i++)
		dp[i][0] = grid[i][0] + dp[i-1][0];
	for(int i=1;i<colLen;i++)
		dp[0][i] = grid[0][i] + dp[0][i-1];
	for(int i=1;i<rowLen;i++)
		for(int j=1;j<colLen;j++)
			dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j];
	return dp[rowLen-1][colLen-1];
}

/**
不像二维数组那样,可以直接对arr[i][j]进行循环赋值。在
vector<vector<int>>中,因为vector是一个容器,最外层的vector容
器中放着更小的vector,而里层的vector里面放的是int型的数字。所
以我们首先要对里层的vector容器赋值,然后再把里层的vector作为元
素插入到外层的vector中。
*/ 
int main()
{
	vector<vector<int> > grid;
	vector<int>temp;
	int m, n;
	cin>>m>>n;
	int x;
	for(int i=0;i<m;i++)
	{
		for(int j=0;j<n;j++)
		{
			cin>>x;
			temp.push_back(x);
		}
		grid.push_back(temp);
	}
	cout<<minPathSum(grid)<<endl;
	return 0;
}

优化明天再来更。


更新: 使用一维数组来存放结果,也即滚动数组的思想。

递推式:dp[j] = min(dp[j-1], dp[j]) + grid[i][j];

int minPathSum(vector<vector<int> > &grid) 
{
	const int rowLen = grid.size();
	const int colLen = grid[0].size();
	int dp[colLen];
	dp[0] = grid[0][0];//初值
	for(int i=1;i<colLen;i++)//相当于初始化
		dp[i] = dp[i-1] + grid[0][i];
	for(int i=1;i<rowLen;i++)//递推
		for(int j=0;j<colLen;j++)
		{
			if(j == 0)
				dp[j] += grid[i][j];
			else
				dp[j] = min(dp[j-1], dp[j]) + grid[i][j];
		}
	return dp[colLen-1];
}

继续优化: 使用原数组来存放结果。
递推式:grid[i][j] = min(grid[i][j-1], grid[i-1][j]) + grid[i][j];

int minPathSum(vector<vector<int> > &grid) 
{
	int rowLen = grid.size();
	int colLen = grid[0].size();
	for(int j=1;j<colLen;j++)//初始化
		grid[0][j] += grid[0][j-1];
	for(int i=1;i<rowLen;i++)//初始化
		grid[i][0] += grid[i-1][0];
	for(int i=1;i<rowLen;i++)//计算递推式
		for(int j=1;j<colLen;j++)
			grid[i][j] += min(grid[i][j-1], grid[i-1][j]);
	return grid[rowLen-1][colLen-1];
}
发布了61 篇原创文章 · 获赞 45 · 访问量 6665

猜你喜欢

转载自blog.csdn.net/qq_38861587/article/details/105137688