#include <bits/stdc++.h>
using namespace std;
/*
每次只能向右或向下走
dp[m][n] = dp[m-1][n]+dp[m][n-1];表示走到(m,n)位置的走法
这道题求有多少条路径?那么理所应当想到动态规划。
我们令dp[i][j]是到达i,j最多路径
动态方程:dp[i][j] = dp[i-1][j]+dp[i][j-1];
和上面的公式是一样的
对于第一行dp[0][j]和第一列dp[i][0],由于都是在边界,所以只能为1
时间复杂度O(m*n)
空间复杂度O(m*n)
*/
int uniquePaths(int m,int n)
{
/*
dp[i][j]是到达i和j最多的路径
但是为什么i=0的时候 都要弄成1呢?
因为这是初始化过程最上面和最左边的都是1
*/
vector<vector<int>> dp(m,vector<int>(n,0));
for(int i = 0;i<m;i++)
dp[i][0]=1;
for(int j = 0;j<n;j++)
dp[0][j]=1;
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];
}
}
return dp[m-1][n-1];
}
/*
优化1:
由于dp[i][j]=dp[i-1][j]+dp[i][j-1],因此只需要保留当前行与上一行的数据(在动态方程中,即pre[j] = dp[i-1][j]),空间复杂度O(2n)
其实就是:
当前的状态只跟上一行的状态和同一行左边的状态相关。所以我们只需要维护上一行的数组,和当前行的数组。那么pre就是上一行的状态(整行),cur就是当前行的状态。
*/
int uniquePaths1(int m,int n)
{
vector<int>pre(n);
vector<int>cur(n);
//初始化 把所有的值都填成1
for(int i = 0;i<n;i++)
{
pre[i] = 1;
cur[i] = 1;
}
for(int i = 1;i<m;i++)
{
for(int j = 1;j<n;j++)
cur[j] = cur[j-1]+pre[j];
}
return cur[n-1];
}
/*
优化2:
cur[j] += cur[j-1];即cur[j] = cur[j]+cur[j-1];
等价于思路二: cur[j] = pre[j]+cur[j-1];
因此,空间复杂度为O(n)。
*/
int uniquePaths2(int m,int n)
{
vector<int>cur(n);
for(int i = 0;i<n;i++)
cur[i] = 1;
for(int i=1;i<m;i++)
{
for(int j=1;j<n;j++)
{
cur[j] += cur[j-1];
}
}
return cur[n-1];
}
int main()
{
int m = 5,n = 8;
int num = uniquePaths2(m,n);
cout<<num<<endl;
system("pause");
return 0;
}