1,不同路径
想法1:dfs暴力搜索每一条路径,不出意外超时了,就当做复习了一下
class Solution {
public:
bool book[105][105];
int nxt[2][2]={{0,1},{1,0}},cnt=0;
void dfs(int x,int y,int m,int n)
{
if(x==m&&y==n)
{
cnt++;
return;
}
for(int i=0;i<2;i++)
{
int tx=x+nxt[i][0];
int ty=y+nxt[i][1];
if(tx<1||tx>m||ty<1||ty>n||book[tx][ty])continue;
book[tx][ty]=true;
dfs(tx,ty,m,n);
book[tx][ty]=false;
}
}
int uniquePaths(int m, int n) {
book[1][1]=true;
dfs(1,1,m,n);
return cnt;
}
};
想法2:数学方法 哪n=3,m=8举例,一共要走n-m-2步也就是8步,其中两步要往下走,答案就是C82=28.
不出意外爆long long,因为求组合数要除一个阶乘
class Solution {
public:
int uniquePaths(int m, int n) {
long long ans=1;
if(m==1||n==1)
return ans;
int x=min(m,n);
long long divide=1;
for(int i=1;i
想法3:回归正题,使用dp
1,dp[i][j]含义:从起点(1,1)开始到(i,j)的路径数
2,递推公式:因为要到某个点,只能有上面的点往下走,或从左边的点往右走
所以dp[i][j]=dp[i-1][j]+dp[i][j-1];
3.初始化:dp[i][1]=1;dp[1][i]=1;
4.遍历顺序:按照二维数组从左到右遍历即可
事实证明,dp是可以过的
class Solution {
public:
int uniquePaths(int m, int n) {
int dp[105][105];
for(int i=1;i<105;i++)dp[i][1]=1;
for(int j=1;j<105;j++)dp[1][j]=1;
for(int i=2;i<=m;i++)
{
for(int j=2;j<=n;j++)
{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
return dp[m][n];
}
};
2.不同路径2
这题与上一题的不同之处在于有了障碍物,这会带来两点不同(为了方便,我把起始点设为(0,0))
1,初始化不同,如果dp[i][0]是障碍物,其后面的块都走不到,值设为0,即可
2,有障碍物的点与正常点不同,dp[i][j]设为0即可
class Solution {
public:
int uniquePathsWithObstacles(vector>& obstacleGrid) {
int dp[105][105]={0};
int m=obstacleGrid.size();
int n=obstacleGrid[0].size();
for(int i=0;i
3.整数拆分
初看就觉得这题很玄学,不知道怎么下手,然后看了题解大概知其意
1,dp[i]的含义:分解i所得的最大乘积
2.递推公式 通过从1到i-1遍历j,获得dp[i]的方法有两种j*(i-j)可以理解为简单的拆成两个数相乘,j*dp[i-j].可以理解为将(i-j)拆开,分成多个数相乘,对于通一个j两者取最大值即可,此外对于同一个i,不同的j,dp[i]也要取最大值.所以dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));
3.初始化:dp[0]和dp[1]无意义,不用初始化,dp[2]=1;即可
4,遍历顺序:dp[i]依赖于dp[i-j],故从前向后遍历即可
class Solution {
public:
int integerBreak(int n) {
int dp[65]={0};
dp[2]=1;
for(int i=3;i<=n;i++)
{
for(int j=1;j