一、不同路径
(1)dp数组含义:到达坐标为[i][j]点的方法有多少种
(2)递推公式:dp[i][j]=dp[i-1][j]+dp[i][j-1]
(3)dp数组初始化:最上面一排和最左侧一列为1
(4)遍历顺序:由上到下,由左到右
(5)返回第(m,n)个点的方法数,即第[m-1][n-1]个坐标
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>>dp(m,vector<int>(n,0));
for(int i=0;i<n;i++)dp[0][i]=1;
for(int j=0;j<m;j++)dp[j][0]=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]点的方法有多少种
(2)递推公式:
①dp[i][j]=dp[i-1][j]+dp[i][j-1]
②dp[i][j]=0(当有障碍的时候,直接把它赋值为0)
(3)dp数组初始化:最上面一排和最左侧一列为1
(4)遍历顺序:由上到下,由左到右
(5)返回第(m.n)个点的方法数,即第[m-1][n-1]个坐标
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m=obstacleGrid.size();
int n=obstacleGrid[0].size();
vector<vector<int>>dp(m,vector<int>(n,0));
for(int i=0;i<m&&obstacleGrid[i][0]==0;i++)dp[i][0]=1;
for(int j=0;j<n&&obstacleGrid[0][j]==0;j++)dp[0][j]=1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(obstacleGrid[i][j]==1){
dp[i][j]=0;
}
else{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
}
return dp[m-1][n-1];
}
};
三、整数拆分
(1)dp数组含义:n为i时拆分后的最大乘积
(2)递推公式:dp[i]=(i-j)*j 和dp[i-j]*j(取二者最大值) 前者是拆成两个数的情况,后者是拆成多个数的情况
(3)dp数组初始化:dp[0]=0,dp[1]=0,dp[2]=1
(4)遍历顺序:从前往后递推
(5)返回第n个数
class Solution {
public:
int integerBreak(int n) {
vector<int>dp(n+1);
dp[0]=0;
dp[1]=0;
dp[2]=1;
for(int i=3;i<=n;i++){
for(int j=1;j<=i/2;j++){//j<=i-j
dp[i]=max(dp[i],max(j*dp[i-j],j*(i-j)));//一个是拆成两个数,一个是拆成多个数
}
}
return dp[n];
}
};