[动态规划与回溯算法] 路径问题

第一层 三角矩阵

题目描述:
在这里插入图片描述

大白话:计算顶部到底步的路径,路径值相加求这个三角形的路径和中值最小,且每一步看一移动到当前位置的下一行,或下一行下一个 如 index:(i,j) --> (i-1,j) 或(i-1,j-1)


思路1:

“三”

状态抽象:

由题可以知道我们需要求最小路径和,也就是最后最后一个位置的路径和,那么我们就可以先求第i个位置 如图所示:
在这里插入图片描述
那么我们要知道到i节点的路径和,就和求最后位置一样,且我们还需要保存第i个状态的结果,因为 i 这个结果是 i+1 个位置需要的


状态的转移方程:

由上述分析可以得出(i,j)这个位置可以访问的 (i-1,j) (i-1,j-1),这个其实就是他的状态转移方程,且是他们中的最小值

特殊状况:

在这里插入图片描述

当节点为当前行第一个和最后一个的时候 , 那么可以访问他的路径只有路径只有 1个

  1. 60 index=[2,0]–>[1,0] (i-1,j)
    –>[1,-1]明显下标没有(i-1,j-1)
  2. 70 index=[2,3]–>[1,3]–>明显上一路径也没有 (i-1,j)
    –>[1,2] 明显下标没有(i-1,j-1)

状态初始化

状态初始化,其实现在来看已经显而易见了,其实就是(0,0) 这个位置,因为这个位置的路径和就是他本身


”一“
显然动归这一类题是需要保存之前求出来的解,一般是由数组来储存,由题可以看出要用一个二维数组去存储解

代码:


    int minimumTotal(vector<vector<int> > &triangle)
    {
        //写法自上到下
        //1.走到(x,y)这个位置只有俩种情况--> 1. (x-1,y) 2.(2-1,y-1)
        //2.特殊情况,在左右俩边的节点的路径是唯一确定的
        
        
        //初始状态
        //triangle[0][0]
        
        //状态的定义与状态的转移方程
        int i=0;
        //状态定义
        for(i =1;i<triangle.size();i++)
        {
            for(int j=0;j<triangle[i].size();j++)
            {
                 //转移方程
                //特殊情况
                if(j==0)
                {
                    triangle[i][j]+=triangle[i-1][j];
                }
                else if(j==i)
                {
                     triangle[i][j]+=triangle[i-1][j-1];
                }
                
                else
                {
                    triangle[i][j]+=min(triangle[i-1][j],triangle[i-1][j-1]);//找最小的值
                }
            }
        }
        
        
        
        //寻找最小值
        for(int j=1;j<triangle[i-1].size();j++)
        {
                   if(triangle[i-1][0]>triangle[i-1][j])
                   {
                       triangle[i-1][0]=triangle[i-1][j];//把最小值放到最后一行第一个位置
                   }
        }
          
        return triangle[i-1][0];//返回结果
    }

优化:

上面你会发现好麻烦呀,最烦的是那么多限制条件,最后还要遍历找最小的路径很就不太人性,没事下面我们思维来拐个弯,我们可不可以把最后一个节点当做初始状态,从下往上找那么我们就不需要找最小路径了

在这里插入图片描述

初始状态:

我们直接把最后一行看作初始状态

在这里插入图片描述

转移方程

当 index:(i,j) 他可以访问 (i+1,j) 或 (i+1,j+1) ,这就是他的转移方程,依旧是俩者中的最小值

在这里插入图片描述

代码:

   int minimumTotal(vector<vector<int> > &triangle)
    {
    
        //初始状态
        //整个triangle[最后一行][0]~~triangle[最后一行][最后一个]
        
        
        //定义状态和转移方程
        for(int i =triangle.size()-2;i>=0;--i) //i为倒数第二行 
        {
            for(int j =0;j<triangle[i].size();j++)
            {
                triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1]);//俩者中最小的那个
            }
        }
           return  triangle[0][0];
    }




第二层 机器人到终点的路径

题目描述:

在这里插入图片描述


思路:

由题可以得知🤖️只可以向下或者向右移动,这个很关键,那么我们可以知道要求最终路径和(设最终路径为 x,y) 其实就是 上一行当前节点的位置当前行的前一个位置的和, (x-1,y)+(x,y-1)


状态的抽象

那么我们可以先求第i个状态的路径,然后再去推到最终路径

状态的转移方程

其实在上述的分析你已经可以看出他的转移方程是啥了(x-1,y)+(x,y-1)

状态初始化

知道🤖️只可以向右或者向下走,那么(0,j) 和(i,0)都为1,黄色区域为1

在这里插入图片描述

因为第一行和第一列的状态都是已知的所以我们只需要从(1,1)这个状态开始求路径个数


代码:

 int uniquePaths(int m, int n)
    {

        //一
        //保存i状态的解的容器
        vector<vector<int>>explain;
        vector<int> d1;
        //初始状态
        //第一行与第一列都为1
        d1.resize(m,1);
        explain.resize(n,d1);


        //状态定义与转移方程
        //转移方程:(i,j) = (i-1,j) 或(i,j-1)
        for(int i =1;i<n;i++)
        {
            for(int j =1;j<m;j++)
            {
                explain[i][j]=explain[i-1][j]+explain[i][j-1];
            }
        }

        //返回结果
        return explain[n-1][m-1];
    }


唠唠家常

我发现类似第一题这样如果 从前往后,自上而下 或 正序写如果很麻烦那么逆序一般情况来说都比较简单,只要脑子转个弯好多问题都变得简单了

在这里插入图片描述

  • 20
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
当谈到动态规划算法回溯算法和贪心算法时,它们都是解决优化问题的经典算法。下面我会对每个算法进行详细讲解: 1. 动态规划算法(Dynamic Programming): 动态规划算法通常用于解决具有重叠子问题和最优子结构性质的问题。它通过将问题分解为子问题,并利用子问题的解来构建更大规模的问题的解。动态规划算法通常使用一个表格或数组来存储中间结果,避免重复计算。其基本思想是通过保存并重复使用子问题的解来减少计算量。 2. 回溯算法(Backtracking): 回溯算法是一种通过试错的搜索方法,用于求解满足一定条件的所有可能的解。回溯算法通过尝试每一种可能的选择并在达到不可行解时进行回溯,即返回上一层并尝试其他选择。回溯算法通常使用递归来实现,它能够穷尽所有可能的解空间,并找到满足条件的解。 3. 贪心算法(Greedy Algorithm): 贪心算法是一种通过每一步的局部最优选择来构建整体最优解的算法。贪心算法在每个步骤上都选择当前最优的解,而不考虑整体未来的结果。它通常不会回溯或重新评估之前的选择。贪心算法适用于一些特定类型的问题,如最小生成树、最短路径等,但并不适用于所有问题。 这三种算法各有优势和局限性,选择哪种算法取决于问题的性质和要求。动态规划算法通常适用于具有重叠子问题和最优子结构的问题回溯算法适用于穷尽搜索所有可能解的问题,而贪心算法适用于局部最优解构成整体最优解的问题。在选择算法时,需要根据问题的特点和约束进行综合考虑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值