leetcode64. 最小路径和---动态规划

给定一个包含非负整数的 m x n 网格,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。

说明:每次只能向下或者向右移动一步。

示例:

输入:
[
  [1,3,1],
  [1,5,1],
  [4,2,1]
]
输出: 7
解释: 因为路径 1→3→1→1→1 的总和最小。

思路:

状态方程为:

S[i][j]=A[i][j] + max(S[i-1][j], if i>0 ; S[i][j-1], if j>0)

注意不要让矩阵的系数为负,还有二维的vector的初始化

class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
	int n=grid.size();//hang line
	int m=grid[0].size();//lie row
	int **dp=new int * [n];
	for(int i=0;i<n;i++)
		dp[i]=new int[m];
	for(int i=0;i<n;i++)
		memset(dp[i],0,sizeof(int)*m);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(i==0)
			{
				if (j!=0)
					dp[i][j]=dp[0][j-1]+grid[0][j];
				else
					dp[i][j]=grid[0][0];
			}
			else if(j==0)
				dp[i][j]=dp[i-1][0]+grid[i][0];
			else {
				dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j];
			}               
		}
	}
	return dp[n-1][m-1];
}
};

调试代码:

可以输出路径:

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

int** minPathSum(vector<vector<int>>& grid) {
	int n=grid.size();//hang line
	int m=grid[0].size();//lie row
	int **dp=new int * [n];
	for(int i=0;i<n;i++)
		dp[i]=new int[m];
	for(int i=0;i<n;i++)
		memset(dp[i],0,sizeof(int)*m);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(i==0)
			{
				if (j!=0)
					dp[i][j]=dp[0][j-1]+grid[0][j];
				else
					dp[i][j]=grid[0][0];
			}
			else if(j==0)
				dp[i][j]=dp[i-1][0]+grid[i][0];
			else {
				dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j];
			}               
		}
	}
	return dp;
}

int main()
{
	vector<vector<int>> grid(3);
	for(int i=0;i<grid.size();i++)
		grid[i].resize(3);
	grid[0][0]=1;	grid[0][1]=3;	grid[0][2]=1;
	grid[1][0]=1;	grid[1][1]=5;	grid[1][2]=1;
	grid[2][0]=4;	grid[2][1]=2;	grid[2][2]=1;
	int** dp=minPathSum(grid);
	for(int i=0;i<grid.size();i++){
		for(int j=0;j<grid[0].size();j++)
			cout<<dp[i][j]<<" ";
		cout<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_37561165/article/details/81110413