一、题目解析
题目还是很简单的,大家一看就懂了,我就不多bb了,直接算法原理。
二、算法原理
1、状态表示:
我们先来分析一个状态表示,题目问我们什么?它问我们从m * n网格的左上角出发,到达m * n位置一共有多少条路径,那么我们直接就根据题目要求定义一个状态表示。
dp[i][j]表示:到达[i][j]位置一共有多少条路径。
2、状态转移方程:
题目说我们只能向下或者向右走一步,因此我们如果要到达[i][j]位置我们只可能从[i-1][j]和[i][j-1]这两个位置走一步到达[i][j]位置,这个没问题吧?也就是说如果我知道有多少条路径可以到达[i-1][j],那么在这每一种路径后面在走上一步是不是就到达[i-1][j]了呢?那么我们怎么知道呢?不就是在dp[i-1][j]里面存着吗?同理,到达[i][j-1]的路径也在dp[i][j-1]里面存着。因此我们就可以推出状态转移方程了。
dp[i][j] = dp[i-1][j] + dp[i][j-1]
3、初始化
接下来我们考虑一下初始化的问题。我们初始化的时候是要用到到上面一个位置和左面一个位置的状态,因此这里初始化的时候,我们可以多加一行,多加一列。这种初始化方式是非常好用的,很多动态规划的题目都会用到这种初始化方式。但是仅仅多加一行多加一列就可以了吗?当然不是,我们还要考虑我们在起点的时候,到达起点有多少条路径呢?是不是就一条呀?自己到达自己呀,因此,我们要只需要将起始位置左边的状态或者上面的状态初始化为1。其它位置初始化为0即可。
4、填表:
填表的顺序大方向是从上往下填表,每一行是从左往右填表。
5、返回结果
因为我们多加了一行多加了一列,因此我们返回dp[m][n]即可。
三、编写代码
希望大家可以先根据算法原理自己尝试编写一下代码,一定要自己尝试一下。
class Solution
{
public:
int uniquePaths(int m, int n)
{
//1、创建一个dp表
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
//2、初始化
dp[0][1] = 1; //dp[1][0] = 1;这样初始化也可以
//3、填表
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
//4、返回结果
return dp[m][n];
}
};