C++-时间复杂度

news2024/9/21 4:29:31

前言

        OJ测试中最烦人的结果莫过于TLE(Time Limit Exceed 超时)MLE(Mempry Limit Exceed超内存)了,在递归和搜索题里面看见这两货就烦。

目录

前言

时间复杂度 

        时间复杂度概念

时间复杂度的表示法

        时间复杂度OJ测试要求

         时间复杂度例举

剪枝

                  1.可行性剪枝

2.最优性剪枝

3.记忆化搜索

4.搜索顺序剪枝


时间复杂度 

        时间复杂度概念

        C++时间复杂度是指算法在处理数据时所需要的计算时间。在C++中,常见的时间复杂度包括常数级别、对数级别、线性级别、平方级别、立方级别等。其中,常数级别是最快的,而立方级别是最慢的。具体来说:
常数级别:只需要一次计算即可完成,如赋值操作等。
对数级别:需要不断缩小问题规模,通常用于二分查找等算法。
线性级别:随着问题规模增加,所需计算时间也呈线性增长,如遍历一个数组等。
平方级别:通常是嵌套循环的形式,所需计算时间随着问题规模的增加呈平方级别增长。
立方级别:通常是三层嵌套循环的形式,所需计算时间随着问题规模的增加呈立方级别增长。
当然,在实际应用中,我们需要选择合适的算法来降低时间复杂度。例如,可以使用哈希表来加速查找操作,或者使用动态规划来减少重复计算等。在竞赛中,一般算机一秒能执行5x10^8次汁算。

时间复杂度的表示法

对于表示时间复杂度,我们可以使用O()表示法来表示时间复杂度,O(n)表示程序运行n次汁算。判断时,只关注最高次项。但执行的数量不是不确定的都填1
比如下面的例子:

O(c) = O(1)     (c表示常数)
O(2n+1) = O(n)
O(+n+1) = O(n²)
O(3+1) = O(n³)


注意:符号 O(c)表示算法或函数具有恒定的时间复杂度,这意味着无论输入大小如何,它都需要固定的时间来执行。 

        时间复杂度OJ测试要求

        为了避免TLE,OJ中要减少时间复杂度,一般来讲(1000ms) n的数据范围大致如下

            时间复杂度                            n算法数据范围
              O(n)                                n < 10^8
           O(log{n})                                n < 10^6
            O(\sqrt{n})                                n < 10^5
        ​​​​​​​     O(n^2)        ​​​​​​​        ​​​​​​​        ​​​​​​​      n<5000
        ​​​​​​​     O(n^3)        ​​​​​​​        ​​​​​​​        ​​​​​​​       n <300
        ​​​​​​​     O(n!)        ​​​​​​​        ​​​​​​​        ​​​​​​​        n < 11

         时间复杂度例举

O(1)     一般的输入输出,变量的定义 ,时间复杂度都为O(1)

printf("Hello,Wold");
int a=3,b=20;
return 0; //时间复杂度为O(1)

O(n)     一般的循环 ,时间复杂度都为O(n)

O(n^2)     一般的二重循环 ,时间复杂度都为O(n^2)

int n=123456;
for(int i=0;i<=n;i++){
    for(int j=0;j<=i;j++) 
        cout<<"# ";
    cout<<endl;
}  
return 0; //时间复杂度为O(n^2)

O(n^3)     一般的三重循环 ,时间复杂度都为O(n^3)

O(2^n)     指数阶,如递归实现的斐波那契数列 ,时间复杂度都为O(2^n)

O(log n)     对数阶,如二分查找 ,时间复杂度都为O(log n) 

O(n log n)     线性对数阶,例如快速排序,时间复杂度都为O(log n) 

剪枝

搜索是OI之路上,人人必会的强大算法。自古便有名言:“暴力进省队”(实际上,很多考试你打好所有暴力就可以拿到不错的分数)。在考场上,搜索常常是与正解的对拍板子(当然有时搜索就是正解),且一般搜索都会有20~30分。而想要写好搜索,剪枝必不可少(有时出题人不会给纯暴力分)。

what's 剪枝?

常用的搜索有Dfs和Bfs。Bfs的剪枝通常就是判重,因为一般Bfs寻找的是步数最少,重复的话必定不会在之前的情况前产生最优解。深搜,它的进程近似一颗树(通常叫Dfs树)。而剪枝就是一种生动的比喻:把不会产生答案的,或不必要的枝条“剪掉”。剪枝的关键就在于剪枝的判断:什么枝该剪,什么枝不该剪,在什么地方减。常用的剪枝有:可行性剪枝、最优性剪枝、记忆化搜索、搜索顺序剪枝。

1.可行性剪枝

就是将搜索树里面不能走的或者走了会走到死胡同的枝条进行减去。

在很多情况下,并不是搜索树中的所有枝条都能通向我们需要的结果,很多的枝条实际上只是一些死胡同。如果我们能够在刚刚进入这样的死胡同的时候,就能够判断出来并立即剪枝,程序的效率往往会得到提高。

在程序上就是:如果当前条件不合法就不再继续搜索,直接return。这是非常好理解的剪枝,搜索初学者都能轻松地掌握,而且也很好想。一般的搜索都会加上。

2.最优性剪枝

一般要自己构造一个估值函数,由该估值函数计算上界和下界,最优性剪枝又是如何进行的呢?当我们处在搜索树的枝条上时,可以通过某种方法估算出该枝条上的所有解的评价函数的上界,即所谓估价函数。显然,大于当前保存的优度的下界,是该枝条上存在最优解的必要条件,否则就一定可以剪枝。所以,最优性剪枝也可以称为“上下界剪枝”。同时,我们也可以看到,最优性剪枝的核心问题就是估价函数的建立。一般实现:在搜索取和最大值时,如果后面的全部取最大仍然不比当前答案大就可以返回。在搜和最小时同理,可以预处理后缀最大/最小和进行快速查询。

3.记忆化搜索

记忆化搜索其实很像动态规划(DP)。

它的关键是:如果对于相同情况下必定答案相同,就可以把这个情况的答案值存储下来,以后再次搜索到这种情况时就可以直接调用。还有就是不能搜出环来,不能互相依赖。

4.搜索顺序剪枝

在一些迷宫题,网格题,或者其他搜索中可以贪心的题,搜索顺序显得十分重要。我经常听见有人说:“从左边搜会TLE,从右边搜就AC了”之类的语句。其实在迷宫、网格类的题目中,以左上->右下为例,右下左上就明显比左上右下优秀。在一些推断搜索题中,从已知信息最多的地方开始搜索显然更加优秀。在一些题中,先搜某个值大的,再搜某个值小的(比如树的度数,产生答案的预计),速度明显会比乱搜更快。

搜索的复杂度明显讲不清,这种剪枝自然是能加就加。

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

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

相关文章

C++相关概念和易错语法(19)(继承规则、继承下的构造和析构、函数隐藏)

1.继承规则 继承的本质是复用&#xff0c;是结构上的继承而不是内容上的继承&#xff0c;近似于在子类中声明了父类的成员变量。 &#xff08;1&#xff09;写法&#xff1a;class student : public person 派生类&#xff08;子类&#xff09;&#xff0c;继承方式&…

Cypress UI自动化之安装环境

注&#xff1a;macOS系统 一、git环境 略 二、node环境 1、安装nvm 前提&#xff1a;有装过Homebrew&#xff0c;参考adb使用方法文档 1、安装nvm&#xff1a;首先要保证之前没有安装过node&#xff0c;如果之前安装过&#xff0c;先 brew uninstall node brew install n…

省市县下拉框的逻辑以及多表联查的实例

2024.7.12 一. 省市县的逻辑开发。1、准备&#xff1a;1.1. 要求&#xff1a;1.2 数据库表&#xff1a; 2. 逻辑&#xff1a;3. 方法3.1 创建实体类3.2 数据访问层3.3 实现递归方法3.4 控制器实现3.5 前端处理 二、多表联查&#xff08;给我干红温了&#xff09;1. 出现了问题2…

Java性能优化-switch性能优化-用String还是int做比较

场景 Java中使用JMH(Java Microbenchmark Harness 微基准测试框架)进行性能测试和优化&#xff1a; Java中使用JMH(Java Microbenchmark Harness 微基准测试框架)进行性能测试和优化_java热点函数-CSDN博客 参考以上性能测试工具的使用。 下面针对Java中对switch-case比较时…

LLM 合成数据生成完整指南

大型语言模型是强大的工具&#xff0c;不仅可以生成类似人类的文本&#xff0c;还可以创建高质量的合成数据。这种能力正在改变我们进行 AI 开发的方式&#xff0c;特别是在现实世界数据稀缺、昂贵或隐私敏感的情况下。在本综合指南中&#xff0c;我们将探索 LLM 驱动的合成数据…

访问控制的定义与原理

访问控制(Access Control)是一种重要的安全机制&#xff0c;用于限制对程序中的数据、函数、类以及计算机系统中资源(如文件、数据库、网络设备等)的访问权限。其主要目的是保护系统中的敏感信息和资源&#xff0c;防止未经授权的访问和操作&#xff0c;确保系统的安全性、完整…

无向图的双连通分量——AcWing 395. 冗余路径

无向图的双连通分量 定义 在无向图中&#xff0c;一个双连通分量&#xff08;Biconnected Component, BCC&#xff09;是指这样的子图&#xff1a;删除其中任意一个顶点都不会使这个子图分离成两个或更多个不相连的子图。换句话说&#xff0c;双连通分量是无割点的极大连通子…

lua 脚本语言 : 基础到高级语法

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

[Python学习篇] Python异常

什么是异常&#xff1f; 异常&#xff08;Exception&#xff09;是指在程序执行过程中发生的错误事件&#xff0c;它会中断程序的正常执行流程。异常可以由程序中的错误引发&#xff0c;也可以通过主动抛出异常来处理特殊情况。Python 使用异常处理机制来捕获和处理这些错误&am…

初识c++(构造函数,析构函数,拷贝构造函数,赋值运算符重载)

一、类的默认函数 默认成员函数就是用户没有显式实现&#xff0c;编译器会自动生成的成员函数称为默认成员函数。 #include<iostream> using namespace std; class Date { public:Date(){_year 1;_month 1;_day 1;cout << _year << "/" <&…

日常的学习

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Android ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 正文 7.11 resAndroidManifest 笔记 <> <> selector shape resources main下的AndroidMainifest.xml文件 application …

sql注入时间盲注

基于时间的盲注 也叫延时注入。通过观察页面&#xff0c;既没有回显数据库内容&#xff0c;又没有报错信息也没有布尔类型状态&#xff0c;那么我们可以考虑用“绝招”--延时注入。延时注入就是根据页面的响应时间来判断是否存在注入&#xff0c;一点一点注入出数据库的信息。我…

【进阶】利用python内置模块自动化发送邮件及邮件附件

目录 自动化发送邮件 流程&#xff1a; 步骤&#xff1a; 【重点】 【MIMEText--发送文本类型的邮件】 【MIMEImage-发送附件为图片的邮件】 【MIMEBase--发送附件为html报告的邮件】 自动化发送邮件 以qq邮箱为例&#xff0c;提前打开POP3/IMAP/SMTP/Exchange/CardDAV 服…

【web]-信息收集-空白页面

打开是一张图 查看源码&#xff0c;发现就一个链接是有用信息&#xff0c;用目录扫描工具&#xff0c;没有发现有价值的信息。 F12&#xff0c;查看请求和相应信息&#xff0c;在响应头中发现了信息。 还有一个小技巧&#xff1a;点击手机图标&#xff0c;可以切换到手机模式中…

Web浏览器485通讯读取RFID卡号js JavaScript

本示例使用设备&#xff1a;485通讯液显带键盘RFID打菲计件读卡器工位机串口可二次开发编程-淘宝网 (taobao.com) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> …

计组_总线

2024.06.21&#xff1a;计算机组成原理总线学习笔记 第23节 总线 3.1 总线的基本概念&#xff08;联想数据通路&#xff09;3.2 总线的分类3.2.1 片内总线&#xff08;CPU芯片内部的总线&#xff09;3.2.2 系统总线3.2.3 通信总线&#xff08;跨系统&#xff0c;408一般不考&am…

四个“一体化”——构建数智融合时代下的一站式大数据平台

随着智能化技术的飞速发展&#xff0c;尤其是以生成式AI为代表的技术快速应用&#xff0c;推动了数据与智能的深化融合&#xff0c;给数据基础设施带来了新的变革和挑战。如何简化日益复杂的系统架构&#xff0c;提高数据处理效率&#xff0c;降低开发运维成本&#xff0c;促进…

十、(正点原子)Linux阻塞和非阻塞IO

阻塞和非阻塞 IO 是 Linux 驱动开发里面很常见的两种设备访问模式&#xff0c;在编写驱动的时候一定要考虑到阻塞和非阻塞。这里的“IO”并不是我们学习 STM32 或者其他单片机的时候所说的“GPIO”(也就是引脚)。这里的 IO 指的是 Input/Output&#xff0c;也就是输入/输出&…

matlab支持向量机使用错误

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

使用Qt和mitmproxy开发一个抓取网页短视频的万能工具

目录 实现原理 mitmproxy介绍 功能简介 安装 脚本示例 如何使用 解释 注意事项 QT工具实现 其他资源 实现原理 使用WebView组件造一工具,工具可输入网页地址并显示网页内容及播放视频。把工具的代理设置指向mitmproxy的端口服务。配合使用mitmproxy的MITM技术,监…