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];
}