算法---动态规划 II

第5题:三角形矩阵

题目分析

  • 状态定义:从三角矩阵顶部到三角矩阵第i层第j个节点的最短路径f(i,j)
  • 状态之间的转移方程:f(i,j) = min{f(i-1,j),f(i-1,j+1)}
  • 初始状态:f(0,0) = triangle[0][0]
  • 返回结果:min{f(len-1,0),f(len-1,1)...f(len-1,len-1)}其中len = triangle.size()

代码描述

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        if(triangle.empty())
            return 0;
        int len = triangle.size();
        vector<vector<int>> status(triangle);//保存状态,初始状态为status[0][0] = triam=ngle[0][0]
        int fi;//到达第i层的最小路径
        for(int i = 1;i < len;i++)
        {
            for(int j = 0;j <= i;j++)//第i层有i个元素
            {
                if (j == 0)
                {
                     status[i][j] = status[i - 1][j];
                 }
                 else if (j == i)
                 {
                     status[i][j] = status[i - 1][j - 1];
                 }
                 else
                 {
                     status[i][j] = min(status[i - 1][j], status[i - 1][j - 1]);
                 }
                
                status[i][j] += triangle[i][j];
            }
        }
        //找最小
        fi = status[len-1][0];
        for(int i = 0;i < len;i++)
        {
            if(fi > status[len-1][i])
                fi = status[len-1][i];
        }
        return fi;
    }
};

第6题:路径总数

题目分析

  • 状态定义:到达第i,j个节点的方法总和f(i,j)
  • 状态之间的转化方程:f(i,j) = f(i-1,j) + f(i,j-1)
  • 初始状态:f(0,0) = 1
  • 返回结果:f(m-1,n-1)

代码描述

class Solution {
public:
    /**
     * 
     * @param m int整型 
     * @param n int整型 
     * @return int整型
     */
    int uniquePaths(int m, int n) {
        vector<vector<int>> status(m);//保存状态,初始状态status[0][0] = 1
        //初始化
        for(int i = 0;i < m;i++)
        {
            vector<int> tmp(n,1);
            status[i] = tmp;
        }
        for(int i = 0;i < m;i++)
        {
            for(int j = 0;j < n;j++)
            {
                if(i != 0 || j != 0)
                {
                    //状态之间的转移
                    if(j == 0)
                        status[i][j] = status[i-1][j];
                    else if(i == 0)
                        status[i][j] = status[i][j-1];
                    else
                        status[i][j] = status[i-1][j] + status[i][j-1];
                }
            }
        }
        return status[m-1][n-1];
    }
};

第7题:路径总和II

题目分析

基本思路和上一题一样,只是在对状态求解是对f(i-1,j)和f(i,-1)进行了判断,如果为1就不能加入计算如果两个都为1则obstacleGrid[i][j] = 1表示不能到达该位置。

  • 状态定义:到达第i,j个节点的方法总和f(i,j)
  • 状态之间的转化方程:f(i,j) = (f(i-1,j)*(obstacleGrid[i-1][j] = 1) + f(i,j-1)*(obstacleGrid[i][j-1] = 1)
  • 初始状态:f(0,0) = 1
  • 返回结果:f(m-1,n-1)

代码描述

class Solution {
public:
    /**
     * 
     * @param obstacleGrid int整型vector<vector<>> 
     * @return int整型
     */
    int uniquePathsWithObstacles(vector<vector<int> >& obstacleGrid) {
        int row = obstacleGrid.size();//行
        int col = obstacleGrid[0].size();//列
        if(obstacleGrid[row-1][col-1] == 1 || obstacleGrid[0][0] == 1)
            return 0;
        vector<vector<int>> status(row);//保存状态
        //初始化状态status[0][0] = 1
        for(int i = 0;i < row;i++)
        {
            vector<int> tmp(col,1);
            status[i] = tmp;
        }
        //状态之间的转移方程
        for(int i = 0;i < row;i++)
        {
            for(int j = 0;j < col;j++)
            {
                if((i != 0 || j != 0) && obstacleGrid[i][j] != 1)
                {
                    if(j == 0)
                    {
                        if(obstacleGrid[i-1][j] != 1)
                            status[i][j] = status[i-1][j];
                        else
                            obstacleGrid[i][j] = 1;
                    }
                    else if(i == 0)
                    {
                        if(obstacleGrid[i][j-1] != 1)
                            status[i][j] = status[i][j-1];
                        else
                            obstacleGrid[i][j] = 1;
                    }
                    else
                    {
                        if(obstacleGrid[i-1][j] != 1 && obstacleGrid[i][j-1] == 1)
                            status[i][j] = status[i-1][j];
                        else if(obstacleGrid[i-1][j] == 1 && obstacleGrid[i][j-1] != 1)
                            status[i][j] = status[i][j-1];
                        else if(obstacleGrid[i-1][j] != 1 && obstacleGrid[i][j-1] != 1)
                            status[i][j] = status[i-1][j] + status[i][j-1];
                        else
                            obstacleGrid[i][j] = 1;
                    }
                }
            }
        }
        return status[row-1][col-1];
    }
};

第8题:最小路径和

题目分析

第6、7、8题相似,本题只是在f(i-1,j)和f(i,j-1)中选择较小者而已。

  • 状态定义:到达第i,j个节点的方法总和f(i,j)
  • 状态之间的转化方程:f(i,j) = min(f(i-1,j) ,f(i,j-1))
  • 初始状态:f(0,0) = grid[0][0];
  • 返回结果:f(m-1,n-1)

代码描述

class Solution {
public:
    /**
     * 
     * @param grid int整型vector<vector<>> 
     * @return int整型
     */
    int minPathSum(vector<vector<int> >& grid) {
        int row = grid.size();//行
        int col = grid[0].size();//列
        vector<vector<int>> status(grid);//保存状态,初始状态status[0][0]=grid[0][0]
        //状态转化
        for(int i = 0;i < row;i++)
        {
            for(int j = 0;j < col;j++)
            {
                if(i == 0)
                {
                    status[i][j] += status[i][j-1];
                }
                else if(j == 0)
                {
                    status[i][j] += status[i-1][j];
                }
                else 
                    status[i][j] += min(status[i-1][j],status[i][j-1]);
            }
        }
        return status[row-1][col-1];
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂嘚程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值