dp_day2

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

你可能感兴趣的:(算法,动态规划)