当前位置: 首页 > news >正文

[Lc6_记忆化搜索] 不同路径 | 解决智力问题 | 有序三元组中的最大值

目录

1.不同路径

题解

2140. 解决智力问题

题解

2873. 有序三元组中的最大值 

题解


1.不同路径

链接:62. 不同路径

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。

问总共有多少条不同的路径?


题解

这个机器人位于左上角位置,每次只能向右和向下移动

  • 问从开始位置到终点一共有多少种不同的路径。
  • 我们下标从1开始计数,这样就少了很多边界情况。

接下来我们用记忆化搜索解决这个问题。

如果纯记忆化搜索我们只要两步就可以了。

  • 第一步 先想出暴搜(递归)的代码。
  • 第二步 暴搜代码改成记忆化搜索,但是前提是能否改!

1.暴搜(递归)

我们最后向求出的m,n位置有多少种不同的走法

  • 那么就这样搞dfs,dfs我给你两个参数,dfs(i,j)
  • 你直接给我返回1,1到达i,j有多少种走法。

具体dfs你内部怎么走我不关心,我相信你一定能够完成任务。

  • 接下来想想这个函数体 如何设计,我想从1,1到达这个三角的位置一共有多少种方式,其实只用关心两个位置就可以。
  • 因为想到达三角的位置,必须要从这两个圆圈到达,要求只能向右走向下走。
  • 如果此时我知道到达圆圈有多少种方式那在多走一步就走到三角了。
  • 也就是说到达圆圈有多少种方式,到达这个三角也有多少种方式。

因此仅需要达到两个圆圈有多少种方式加起来就是到达三角位置的方式 dfs(i-1,j) + dfs(i,j-1)。

递归出口 我们考虑某个位置的时候,我们仅会考虑它上面的位置以及左边的位置。

  • 有可能i=1的时候去考虑i-1不就越界了吗
  • i=0的时候不能从非法位置达到这里。
  • 同理j=0也是一种非法情况,我们既要考虑上边也要考虑左边。因此

i == 0 || j == 0 return 0;

但还有一种隐藏递归出口

  • 当i == 1 && j == 1的时候是位于起点的
  • 上面和左边都没有所以需要特殊处理 i == 1 && j == 1 return 1
class Solution {
public:
    int uniquePaths(int m, int n) 
    {
        //爆搜
        return dfs(m,n);
    }

    int dfs(int m,int n)
    {
        //出口
        if(m==0 || n==0) return 0;
        if(m==1 && n==1) return 1;

        return dfs(m-1,n)+dfs(m,n-1);
    }
};

上面会超时,下面看看能否暴搜的代码改成记忆化搜索。

在递归过程种发现大量重复的相同问题就可以用记忆化搜索

记忆化搜索

我们发现在递归过程种发现大量重复的相同问题因此可以用记忆化搜索

搞一个备忘录

  • 递归之前,查找一下备忘录
  • 返回之前,把结果存在备忘录中

搞一个备忘录 上一道题是搞一个一维数组,但是这道题dfs函数里面是有两个可变参数,i和j一直在变化。

  • 里面的值是int,因此我可以搞一个int [m+1][n+1] 二维数组。
  • 因为要访问到m,n的位置。

进前 瞅瞅。return 前 存存

class Solution {
public:
    vector<vector<int>> memo;

    int uniquePaths(int m, int n) 
    {
        //记忆化搜索
        memo.resize(m+1,vector<int>(n+1,0));

        return dfs(m,n);
    }

    int dfs(int m,int n)
    {
        if(memo[m][n]) return memo[m][n];
        //出口
        if(m==0 || n==0) return 0;
        if(m==1 && n==1) return 1;

        memo[m][n]=dfs(m-1,n)+dfs(m,n-1);
        return dfs(m-1,n)+dfs(m,n-1);
    }
};

解下来把记忆化搜索改成动态规划。

  1. 多加一层的 初始化
  2. 循环内 要注意起点的值 continue ,防止被修改

2140. 解决智力问题

链接:2140. 解决智力问题

给你一个下标从 0 开始的二维整数数组 questions ,其中 questions[i] = [pointsi, brainpoweri]

这个数组表示一场考试里的一系列题目,你需要 按顺序 (也就是从问题 0 开始依次解决),针对每个问题选择 解决 或者 跳过 操作。解决问题 i 将让你 获得 pointsi 的分数,但是你将 无法 解决接下来的 brainpoweri 个问题(即只能跳过接下来的 brainpoweri 个问题)。如果你跳过问题 i ,你可以对下一个问题决定使用哪种操作。

  • 比方说,给你 questions = [[3, 2], [4, 3], [4, 4], [2, 5]]
    • 如果问题 0 被解决了, 那么你可以获得 3 分,但你不能解决问题 12
    • 如果你跳过问题 0 ,且解决问题 1 ,你将获得 4 分但是不能解决问题 23

请你返回这场考试里你能获得的 最高 分数。


题解

刚好今天的每日一题

  • 暴力 选 or 不选 会超时

class Solution {
public:
    typedef long long ll;
    queue<vector<int>> q;
    ll ret;

    long long mostPoints(vector<vector<int>>& questions) 
    {
        //dp
        dfs(questions,0,0);
        return ret;
    }

    void dfs(vector<vector<int>>& questions,int p,ll count)
    {
        if(p>=questions.size()) //向下 再向上 //暴力 是会经历两次的
        {
            ret=max(ret,count);
            return;
        }
//选
        dfs(questions,p+questions[p][1]+1,count+questions[p][0]);
//不选
        dfs(questions,p+1,count); 
    } 
};

采用 记忆化搜索,记录 结果的记忆化递归,避免 重复进行

class Solution 
{
    int n = 0;
    unordered_map<int, long long> memo;
public:
    long long dfs(vector<vector<int>>& questions, int pos)
    {
        if (pos >= n)
            return 0;

        if (memo.count(pos))
            return memo[pos];

        // 选 - 跳到 pos + brain + 1
        long long ret = questions[pos][0] + dfs(questions, pos + questions[pos][1] + 1);

        // 不选 - 跳到 pos + 1
        ret = max(ret, dfs(questions, pos + 1));

        memo[pos] = ret; //记录 结果的记忆化递归
        
        return ret;
    }

    long long mostPoints(vector<vector<int>>& questions)
    {
        n = questions.size();
        return dfs(questions, 0);
    }
};

采用动态规划,优化


2873. 有序三元组中的最大值 

链接:2873. 有序三元组中的最大值 I

给你一个下标从 0 开始的整数数组 nums

请你从所有满足 i < j < k 的下标三元组 (i, j, k) 中,找出并返回下标三元组的最大值。如果所有满足条件的三元组的值都是负数,则返回 0

下标三元组 (i, j, k) 的值等于 (nums[i] - nums[j]) * nums[k]


题解

暴力

class Solution {
public:
    typedef long long ll;

    long long maximumTripletValue(vector<int>& nums) 
    {
        //暴力
        ll ret=0;
        int n=nums.size();
        for(int i=0;i<n-2;i++)
        {
            for(int j=i+1;j<n-1;j++)
            {
                for(int k=j+1;k<n;k++)
                {
                    ret = max(ret,(ll)(nums[i] - nums[j]) * nums[k]);//!!!强转
                }
            }
        }
        return ret;
    }
};

注意 max 比较对 ll 的强转~

解法二:

类比:11.盛水最多的容器

利用单调性来进行空间换时间

class Solution {
public:
    typedef long long ll;
    long long maximumTripletValue(vector<int>& nums) 
    {
        //利用单调性
        int n=nums.size();
        if (n < 3) return 0;  // 🌟 新增边界条件

        ll ret=0;
        vector<int> max_left(n,0);  //i
        vector<int> max_right(n,0);  //k
        //空间换时间
        for(int j=1;j<n;j++)
        {
            max_left[j]=max(max_left[j-1],nums[j-1]);
//!!!!!存储当前位置所对应的最大左右值
        }
        for(int j=n-2;j>=0;j--)
        {
            max_right[j]=max(max_right[j+1],nums[j+1]);
        }
        for(int j=1;j<n-1;j++)
        {
            ret=max(ret,(ll)(max_left[j]-nums[j])*max_right[j]);
        }
        return ret;
        
    }
};

//!!!!!存储当前位置所对应的最大左右值

http://www.dtcms.com/a/107306.html

相关文章:

  • Ansible内置模块之systemd
  • 【区块链+ 房产建筑】山东省建筑产业互联网平台 | FISCO BCOS 应用案例
  • 【Linux】文件系统知识梳理:从磁盘硬件到文件管理
  • C++IO流类库
  • 单元测试原则之——不要模拟值对象 (1)
  • SIMD技术:定义、与AI的关联及推理加速
  • HarmonyOS-ArkUI Rcp模块类关系梳理
  • Flask+Vue构建图书管理系统及Echarts组件的使用
  • 使用SpringBoot + Thymeleaf + iText实现动态PDF导出
  • pollinations 一个免费文生图、声音、文网站
  • PhotoShop学习05
  • springcloud configClient获取configServer信息失败导致启动configClient注入失败报错解决
  • 安徽京准:GPS北斗卫星校时服务器助力大数据云计算
  • 《Linux内存管理:实验驱动的深度探索》大纲
  • 项目练习:若依系统二次开发中,某些情况下,v-hasPermi不适合的解决办法
  • DoDAF科普
  • Python入门(5):异常处理
  • 蓝桥杯练习:对称二叉树
  • 全国产FMC子卡-16bit 8通道2.4G
  • Leetcode 6207 -- DP | 思维 | 双指针
  • catch-all路由
  • 数据结构初阶: 顺序表的增删查改
  • 【LeetCode Solutions】LeetCode 126 ~ 130 题解
  • Selenium自动化中的 三大时间等待
  • gcc 链接顺序,静态库循环依赖问题
  • 「青牛科技」GC5849 12V三相无感正弦波电机驱动芯片
  • RISC-V debug专栏2 --- Debug Module(DM)
  • 在将asc文件导入maxent文件时出现for input string:“nan“
  • (kotlin) Android 13 高版本 图片选择、显示与裁剪功能实现
  • Docker容器部署Java项目的自动化脚本(Shell编写)