记忆化搜索——1

news2024/11/24 10:58:08

目录

1.斐波那契数

2.不同路径

3.最长递增子序列

4.猜数字大小2

5.矩阵中的最长递增路径


1.斐波那契数

该题规律很明显,就直接放记忆化搜索的版本了

class Solution {
public:
    int dfs(int n)
    {
        if(n==0||n==1)//递归出口
        {
            return n;
        }
        if(f[n-1]==-1)//检查是否已经记忆过
        {
            f[n-1]=dfs(n-2)+dfs(n-3);
        }
        if(f[n-2]==-1)//检查是否已经记忆过
        {
             f[n-2]=dfs(n-3)+dfs(n-4);
        }
        return f[n]=f[n-1]+f[n-2];//状态转移
    }
    int fib(int n) {
        memset(f,-1,sizeof f);
        f[0]=0,f[1]=1;
        dfs(n);
        return f[n];
    }
    int f[31];

};

2.不同路径

 

class Solution {
public:

    int dfs(int x, int y)
    {
        if (x < 1 || y < 1)return 0;//防止越界
        if (x == 1 && y == 1)return f[x][y];//递归出口
        if (f[x][y] == -1)//检查是否记忆
        {
            f[x][y] = dfs(x - 1, y) + dfs(x, y - 1);
        }
        return f[x][y];
    }
    int uniquePaths(int m, int n) {
        memset(f, -1, sizeof f);
        f[1][1] = 1;
        return dfs(m, n);
    }
    long long f[101][101];
};

3.最长递增子序列

class Solution {
public:
    void dfs(vector<int>& nums,int index)
    {
        int ret=1;//临时存放index位置为起点的最长递增子序列长度,因为一个数字最起码长度为1,所以ret默认1
        for(int i=index+1;i<n;i++)
        {
            if(nums[index]<nums[i])
            {
                if(f[i]==0)dfs(nums,i);//检查标记,剪枝操作
                ret=max(ret,f[i]+1);//注意+1,因为f是以i为起点的最长递增子序列长度
            }
        }
        f[index]=ret;
        ans=max(ans,f[index]);
    }
    int lengthOfLIS(vector<int>& nums) {
        n=nums.size();
//以第i位为起点的最长递增子序列长度
        for(int i=0;i<n;i++)
        {
            if(f[i]!=0)continue;
            dfs(nums,i);
        }
//ans存的是这些最长递增子序列中最长的长度
        return ans;
//注意,我试过当前函数直接一个dfs,然后直接返回,因为最后f所有位置都要填上,所以
//我直接在dfs里疯狂展开,没填就展开,也可以过,但是效率比在这里用for循坏差一点,几十毫秒的差距
    }
    int ans=0;
    int n;
    int f[2501];//存以当前位置为起点的最长递增子序列长度
};

4.猜数字大小2

class Solution {
public:
    void dfs(int l,int r)
    {
        if(l>=r)
        {
            return ;
        }
//注意,如果l>r,说明这不是一个合法区间,不用管
//如果l==r,说明没必要付钱,因为这个数字是一定会被找到的
//而f数组默认都是0,所以直接返回就好
        int ret=99999999;
//一个大数,因为下面要用来比小
        for(int i=l;i<=r;i++)
        {
            if(f[l][i-1]==0)dfs(l,i-1);
            if(f[i+1][r]==0)dfs(i+1,r);
//检查标记,剪枝操作
            ret=min(ret,i+max(f[l][i-1],f[i+1][r]));
//这个部分看图,主要是,一个区间最优解是列举区间每个数字作为第一个猜的数,然后一直猜猜到每个数都被猜过为止所花费的金额,这些金额的最小值就是这个区间的最优解。
//每个作为当前区间第一个猜的数所分割的区间,因为是分割,所以是左右区间,根据上面的定义,这个数的最后结果是左右区间最优解中最大的金额加上自身。而每个数都依此算,最后整个区间的最优解就是这些数的结果(金额)的最小值
        }
        f[l][r]=ret;
    }
    int getMoneyAmount(int n) {
        dfs(1,n);
        return f[1][n];
    }
    int f[202][202];//存当前区间的最优解,一维下标是左端,二维下标是右端
};

5.矩阵中的最长递增路径

class Solution {
public:
    bool check(int x, int y) {
        if (x < 0 || y < 0 || x >= m || y >= n)return false;
        return true;
    }
//检查是否越界
    void dfs(vector<vector<int>>& matrix, int x, int y)
    {
        int ret = 1;
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i], ny = y + dy[i];
            if (check(nx, ny) && matrix[x][y] < matrix[nx][ny])
            {
//满足不越界且递增的条件进入if
                if (f[nx][ny] == 0)dfs(matrix, nx, ny);
//检查标记,剪枝。
                ret = max(ret, f[nx][ny] + 1);
//取最大
            }
        }
        f[x][y] = ret;
//记录当前结果
        ans = max(ans, f[x][y]);
//记录最大值
        return;
    }
    int longestIncreasingPath(vector<vector<int>>& matrix) {
        m = matrix.size();
        n = matrix[0].size();
//以每个数字为起点开始找,利用f数组,省略很多重复的dfs展开
        for (int i = 0; i < m; i++)
        {
            for (int j = 0; j < n; j++)
            {
                if (f[i][j] == 0)
                {
                    dfs(matrix, i, j);
                }
            }
        }
        return ans;
    }
    int dx[4] = { 0,0,-1,1 };
    int dy[4] = { 1,-1,0,0 };
    int f[201][201];
    int n, m, ans = 0;
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1986511.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

计算机网络中拥塞控制的门限值怎么设置

拥塞避免的门限值设置主要涉及到加权随机早期检测&#xff08;‌WRED&#xff09;‌技术&#xff0c;‌这是一种拥塞避免机制&#xff0c;‌通过为每个队列设定一对低门限和高门限值来实现。‌具体来说&#xff0c;‌当队列长度小于低门限时&#xff0c;‌不丢弃报文&#xff0…

64 lambda 表达式

lambda 表达式常用来声明匿名函数&#xff0c;即没有函数名字的临时使用的小函数&#xff0c;常用在临时需要一个类似于函数的功能但又不想定义函数的场合。 lambda 表达式只可以包含一个表达式&#xff0c;不允许包含其他复杂的语句&#xff0c;但在表达式中可以调用其他函数…

Flink实战(10)-checkpoint容错保证

0 前言 程序在 Flink 集群运行&#xff0c;某个算子因为某些原因出现故障&#xff0c;如何处理 在故障恢复后&#xff0c;如何保证数据状态&#xff0c;和故障发生之前的数据状态一致? 1 什么是 checkpoint(检查点)? Checkpoint 能生成快照(Snapshot)。 若 Flink 程序崩…

ResNet 网络中的残差单元

今晚看《深度学习推荐系统实战》这本书&#xff0c;读到这样一句话&#xff0c;残差单元中的两层 ReLU 网络其实拟合的是输出和输入之间的“残差” x o − x i x^o-x^i xo−xi &#xff0c;想看看微信读书的 AI 问书新功能对这句话怎么理解&#xff0c;原以为会像其他大模型一…

H20 首发!上 Neolink.AI 免费尝鲜

AI 原生服务平台 Neolink.AI 正式上线&#xff01;Neolink.AI 致力于整合关键要素——算力、数据、知识、模型与企业应用&#xff0c;旨在为 AI-Native 应用的构建提供高效能的 GPU 算力资源和全面的一站式数据与 AI 平台产品服务。 #高性能千卡集群免费尝鲜# 今天&#xff0…

[Vue3] 4 computed

前言 … 目标 1 computed的用法 computed的用法 computed 计算属性用法与vue2的类似 引入 import { reactive,computed } from vue使用 setup(){let person reactive({firstName:张,lastName:三})// 简单写法 - 只有读// person.fullName computed(()>{// return…

Windows11手动安装linux分发版

Manual installation steps for older versions of WSL | Microsoft LearnStep by step instructions to manually install WSL on older versions of Windows, rather than using the wsl install command.https://learn.microsoft.com/en-us/windows/wsl/install-manual下载完…

【算法 03】雇佣问题

“雇用问题”及其算法优化 在日常生活和工作中&#xff0c;我们经常会遇到需要从多个选项中做出选择的情况&#xff0c;而“雇用问题”正是这样一个典型的例子。在这个问题中&#xff0c;我们不仅要考虑如何高效地找到最佳候选人&#xff0c;还要关注整个过程中的成本。今天&a…

Tomcat漏洞

一、Tomcat 漏洞描述 当 Tomcat运行在Windows操作系统时&#xff0c;且启用了HTTPPUT请求方法(例如&#xff0c;将readonly初始化参数由默认值设置为false)&#xff0c;攻击者将有可能可通过精心构造的攻击请求数据包向服务器上传包含任意代码的JSP 文件&#xff0c;JSP文件中…

docker系列11:Dockerfile入门

传送门 docker系列1&#xff1a;docker安装 docker系列2&#xff1a;阿里云镜像加速器 docker系列3&#xff1a;docker镜像基本命令 docker系列4&#xff1a;docker容器基本命令 docker系列5&#xff1a;docker安装nginx docker系列6&#xff1a;docker安装redis docker系…

蒲公英G5-2250路由器之收集各种硬件的配置页面

前言&#xff1a;此篇文章是为了更好的让大家了解各个路由器的后台设置页面具体有哪些功能&#xff0c;更加的清晰直观&#xff01;&#xff08;如有雷同纯属巧合&#xff0c;如有侵权联系删除&#xff01;&#xff09; 云管理平台 本地地址IP/oraybox/login.html 本地配置页…

一把手带你了解Bigo Ads联动休闲真金游戏出海营销策略

一把手带你了解Bigo Ads联动休闲真金游戏出海营销策略 在探索Bigo Ads作为投放海外游戏广告的平台时&#xff0c;精准定位与创意融合成为了成功的关键。首先&#xff0c;深入理解目标市场的文化习俗与玩家偏好至关重要。不同地区的玩家对于游戏类型、画风乃至广告语言风格都有…

【链表OJ】常见面试题 3

文章目录 1.[环形链表II](https://leetcode.cn/problems/linked-list-cycle-ii/description/)1.1 题目要求1.2 快慢指针1.3 哈希法 2.[随机链表的复制](https://leetcode.cn/problems/copy-list-with-random-pointer/description/)2.1 题目要求2.2 迭代法 1.环形链表II 1.1 题目…

KEIL5芯片包下载

一、打开KEIL芯片包下载网址 Arm Keil | Devices 二、搜索要下载的芯片型号 三、安装

CSP初赛知识点讲解(二)

CSP初赛知识点讲解&#xff08;二&#xff09; 进制转换基本定义n进制转十进制十进制转n进制n进制转m进制小数的进制转换 例题训练&#xff08;四&#xff09; 进制转换 基本定义 十进制&#xff1a;逢十进一(包含数字0~9) ( 365 ) 10 3 1 0 2 6 1 0 1 5 1 0 0 (365)_{…

如何提高编程能力?(来自准大三学长的含泪建议)

种一棵树最好是十年前&#xff0c;其次是现在 想了解更多内容可以看我主页&#xff1a;GGBondlctrl-CSDN博客 1.前言 以下是小编的亲身经历哟 &#xff08;1&#xff09;大一&#xff0c;摆烂 -------和每个人一样&#xff0c;大学都是带着美好的憧憬&#xff0c;我开始学习…

Apache漏洞

四、 CVE-2021-41773 Apache HTTP Server 路径穿越漏洞 漏洞简介 该漏洞是由于Apache HTTP Server 2.4.49版本存在目录穿越漏洞,在路径穿越目录<Directory/>Require all granted</Directory>允许被访问的的情况下(默认开启)攻击者可利用该路径穿越漏洞读取到Web…

C++ 基础练习 - Chapter 12 (基础练习 完结版)

Review Questions 12.1 What is generic Programming? How is it implemented in C? Answer: Generic programming is an approach where generic types are used as parameters in algorithms so that they work for variety of suitable data types and data structures…

【Spring】通过Aspects实现面向切面编程(AOP)

目录 1.概念理解 2. 案例说明 1.概念理解 【注】一些概念来自&#xff1a;https://blog.csdn.net/Kaiser__/article/details/135894150 横切关注点 分散在每个各个模块中解决同一样的问题&#xff0c;如用户验证、日志管理、事务处理、数据缓存都属于横切关注点。这个概念不是…

【C++刷题】优选算法——贪心第一辑

什么是贪心算法 贪心策略&#xff1a;局部最优 -> 全局最优 “贪婪鼠目寸光” 1、把解决问题的过程分为若干步 2、解决每一步的时候&#xff0c;都选择当前看起来“最优的”解法 3、“希望”得到全局最优解 贪心算法的特点 贪心策略的提出是没有标准或者模板的 正确的贪心策…