深度优先搜索(DFS)剪枝:记忆化搜索(C++)

news2024/11/15 23:26:13

目录

一、基本思想

二、样例

三、程序 

        1、普通的深度优先搜索

        2、分析 

        3、记忆化搜索 程序

四、实际速度样例


一、基本思想

        今天我们来讲一下深搜的剪枝方法中的一个:记忆化搜索。

        顾名思义,记忆化搜索就是让程序记住一些东西,然后可以在需要用的时候可以瞬间调用,不需要再进行一次复杂的计算!

        怎么记?

        首先,记忆需要大脑来存储数据,什么来模拟大脑? 数组

        其次,记忆需要现有的知识用来记住,知识从哪里来? 以前求出的数据

        这样,我们如果要用到以前求过的数据,就可以从数组中调用,可以大大提高我们程序的运行速度。


二、样例

        斐波那契数列计算:斐波那契数列是这样的:1、1、2、3、5、8、13、21、34……

        发现规律了吗? 第一项和第二项是1,除了前面两个数外,每一个数都是前面两个数的和。

        这样的题大家应该都做过,现在我们规定一下输入输出格式。

        输入格式:

                一个正整数N(1≤N≤90)表示输出斐波那契数列的前N项。

        输出格式:

                共 N 行,每行两个正整数 i、t,表示斐波那契数列第 i 项是 t。

        输入样例:

90

        输出样例:

1 1
2 1
3 2
4 3
5 5
6 8
7 13
8 21
9 34
10 55
11 89
12 144
13 233
14 377
15 610
16 987
17 1597
18 2584
19 4181
20 6765
21 10946
22 17711
23 28657
24 46368
25 75025
26 121393
27 196418
28 317811
29 514229
30 832040
31 1346269
32 2178309
33 3524578
34 5702887
35 9227465
36 14930352
37 24157817
38 39088169
39 63245986
40 102334155
41 165580141
42 267914296
43 433494437
44 701408733
45 1134903170
46 1836311903
47 2971215073
48 4807526976
49 7778742049
50 12586269025
51 20365011074
52 32951280099
53 53316291173
54 86267571272
55 139583862445
56 225851433717
57 365435296162
58 591286729879
59 956722026041
60 1548008755920
61 2504730781961
62 4052739537881
63 6557470319842
64 10610209857723
65 17167680177565
66 27777890035288
67 44945570212853
68 72723460248141
69 117669030460994
70 190392490709135
71 308061521170129
72 498454011879264
73 806515533049393
74 1304969544928657
75 2111485077978050
76 3416454622906707
77 5527939700884757
78 8944394323791464
79 14472334024676221
80 23416728348467685
81 37889062373143906
82 61305790721611591
83 99194853094755497
84 160500643816367088
85 259695496911122585
86 420196140727489673
87 679891637638612258
88 1100087778366101931
89 1779979416004714189
90 2880067194370816120

三、程序 

        1、普通的深度优先搜索

#include <iostream>
#include <cstdio>
using namespace std;
int n; 
long long fbnq(int n)
{
	if (n==1 || n==2)
		return 1;
	return fbnq(n-1)+fbnq(n-2);
}
int main()
{
	cin >>n;
	for (int i=1;i<=n;i++)
		cout <<i <<" " <<fbnq(i) <<endl;
	return 0;
}

        2、分析 

        运行一下,发现前面 40 项还好,到了后面,速度就突然下降,90项的话大概要2000000年!

        那么,我们该怎么办?

        我们可以对这个程序计算过的数进行观察(假设当前要计算的是 fbnq(7) ):

        

         我们发现,这幅图中:

        7 被算了 1 次;

        6 被算了 1 次;

        5 被算了 2 次;

        4 被算了 3 次;

        3 被算了 5 次;

        2 被算了 8 次;

        1 被算了 5 次;

        这个增长率是非常可观的,除了最后一项,其他的数据正好是 斐波那契数列。

        我们知道 斐波那契数列 到达第47项,就可以超过 int 范围! 第93项就可以超过 long long 范围!

        这么大的数,怎么可能不超时?

        再想一想,同样的东西算了很多遍,为什么不用 “大脑” 将它们 记下来呢? 这样就不用重复计算,只需要直接调用就可以了!!!

        OK呀!

        3、记忆化搜索 程序

#include <iostream>
#include <cstdio>
using namespace std;
long long n,a[100];    //数组a 为大脑,这里一点要用 long long,原因自己想
long long fbnq(int n)
{
	if (n==1 || n==2)        //前两项都是 1
		return 1;
	if (!a[n])              //如果记忆为空
		a[n]=fbnq(n-1)+fbnq(n-2);        //记住这个值
	return a[n];        //返回记忆中的值
}
int main()
{
	cin >>n;
	for (int i=1;i<=n;i++)
		cout <<i <<" " <<fbnq(i) <<endl;        //输出
	return 0;
}

        这可能有人要问:为什么不直接用循环搞定呢,又方便又快捷??

        是的,一个循环确实方便许多,但这里主要讲的是方法,这个方法在面对 用深度优先搜索 解决 但是会超时 的题目时,可能用得上。

四、实际速度样例

        看着这两个截然不同的效率,我不禁想到了什么……

#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
long long n,a[11000]; 
long long fbnq1(int n)
{
	if (n==1 || n==2)
		return 1;
	if (!a[n])
		a[n]=fbnq1(n-1)+fbnq1(n-2);
	return a[n];
}
long long fbnq2(int n)
{
	if (n==1 || n==2)
		return 1;
	return fbnq2(n-1)+fbnq2(n-2);
}
void xy(int y,int x) 
{
    COORD  coord;    
    coord.X=x;         
    coord.Y=y;
    HANDLE a=GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(a,coord);
}
int main()
{
	system("mode con cols=180 lines=50");
	srand (time(0));
	cout <<"别人的涨粉速度:\n\n";
	system ("pause");
	system ("cls");
	for (int i=1;i<=10000;i++)
	{
		fbnq1(i);
		xy(rand()%45,rand()%170);
		cout <<"+" <<rand()%3+1;
		xy(rand()%45,rand()%170);
		cout <<"  ";
	}
	Sleep (200);
	system ("cls"); 
	cout <<"我的涨粉速度:\n\n";
	system ("pause");
	system ("cls");
	for (int i=1;i<=43;i++)
	{
		fbnq2(i);
		xy(rand()%45,rand()%170);
		cout <<"+" <<rand()%3+1;
	}
	Sleep (200);
	system ("cls");
	cout <<"生动形象……";
	Sleep(1000000);
	xy(49,179);
	return 0;
}

        看我如此可怜,为什么不给我一个三连呢,又不费什么事……

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

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

相关文章

Stimulsoft Dashboards.JS JavaScript 2203.1.0仪表板

Stimulsoft Dashboards.JS--Ω578867473 Dashboards.JS 是一个功能齐全的工具&#xff0c;用于为 JavaScript 平台创建仪表板。 JavaScript 仪表板 Dashboards.JS 是一个功能齐全的工具&#xff0c;用于为 JavaScript 平台创建仪表板。要生成和查看仪表板&#xff0c;您需要任何…

Qt扫盲-QAbstractButton 笔记总结

QAbstractButton使用总结一、概要1.显示内容2. 快捷键3. 对话框默认按钮4. 按钮状态5. 信号说明6. 自定义按钮QAbstractButton 类实现的是一个抽象按钮。主要是Button类具有的共性&#xff0c;但是处理用户的操作响应、并绘制不同按钮的形式是由子类来完成的。一、概要 QAbstr…

图文深度解析Linux内存碎片整理实现机制以及源码

图文深度解析Linux内存碎片整理实现机制以及源码。 物理内存是以页为单位进行管理的,每个内存页大小默认是4K(大页除外)。申请物理内存时,一般都是按顺序分配的,但释放内存的行为是随机的。随着系统运行时间变长后,将会出现以下情况: 在多道程序当中,如果要让我们的程…

深度解析车载域控制器

文章目录域控制器域控制器的组成ADAS域控制器智能座舱域HUD仪表盘IVI域控制器的发展域控制器对传统ECU的挑战域控制器 ​ 随着车辆的信息化程度的发展&#xff0c;车辆的ECU也越来越多&#xff0c;从引擎控制、转向助力、仪表、影音等&#xff0c;传统的汽车电子电气架构是分布…

基于Intel® Core™ i5 机器人控制器

XM-6815是一款基于Intel 11代酷睿i系列平台CPU壁挂式电脑&#xff0c;扩展内存槽&#xff0c;1mSATA&#xff0c;3千兆网口&#xff0c;6COM&#xff0c;4USB 3.0&#xff0c;4USB 2.0。该产品适合工业机器人控制器、机器视觉控制器等壁挂安装应用场景. 产品规格 产品类型Inte…

阿里巴巴内部不传之秘「十亿级并发系统顶级教程」GitHub一夜封神

何为超大流量&#xff1f; 超大流量是一个很容易理解的意思!举个例子&#xff1a;现在国内疫情反弹&#xff0c;每个小区都要做核酸那么如果同一时间下来一大批人一起做核酸&#xff0c;那么这就是大流量&#xff0c;然后志愿者将人员进行分配排队让医务人员处理的过来那么这就…

Qt5.6.1移植海思Hi3521d(二)

系列文章目录 Qt5.6.1移植海思Hi3521d&#xff08;一&#xff09; 前言 该篇讲解一下&#xff0c;使用海思交叉编译器arm-hisiv500-linux-gcc&#xff0c;编译qt5.6源码&#xff0c;搭建qt交叉编译环境 一、修改qmake.conf 打开文件~/Project/qt-everywhere-opensource-src-5…

Python制作简易版烟花,没资金买烟花就来做个电子版的吧

前言 听说有人说我很久没更新了&#xff0c;那今天来表演个粒子烟花 跨年倒计时20天&#xff1f;我已经开始整烟花了&#xff0c;虽然不是很好看吧&#xff0c;但是也能将就看看 &#x1f625; 这个的背景图&#xff0c;音乐&#xff0c;还有文字都是可以自己修改的哦 效果…

[附源码]JAVA毕业设计-心理健康管理-(系统+LW)

[附源码]JAVA毕业设计-心理健康管理-&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&a…

String 创建了几个对象?

问题一 String zy1 “小朱”; String zy2 “小朱”; 复制代码 问题二 String zy1 “小朱”; String zy2 “大朱”; 复制代码 问题三 String zy1 new String(“小朱”); String zy2 new String(“小朱”); 复制代码 问题四 String zy1 new String(“小朱”);…

09 - 主引导程序控制权的转移

---- 整理自狄泰软件唐佐林老师课程 文章目录1. BootLoader内存布局2. 通过FAT表加载文件内容3. 编程实验&#xff1a;Loader文件内容的加载4. 第一个Loader程序4.1 汇编小贴士&#xff1a;标志寄存器4.2 编程实验&#xff1a;控制权转移5. 小结1. BootLoader内存布局 2. 通过F…

你还不知道「并发下的三色标记」么?

引用计数算法 在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时 计数器值就加一;当引用失效时&#xff0c;计数器值就减一; 任何时刻计数器为零的对象就是不可能再被使用的。 引用计数算法的缺陷 如下面代码&#xff0c;两个对象互相引用导致无法回收♻️ 对…

【OpenCV学习】第12课:特征提取(高斯不同)

仅自学做笔记用,后续有错误会更改 理论 定义&#xff1a;就是把同一张图像在不同的参数下做高斯模糊之后的结果相减&#xff0c;得到的输出图像&#xff0c;称为高斯不同&#xff08;DOG&#xff09;高斯不同是图像的内在特征&#xff0c; 在灰度图像增强丶角点检测中经常用到…

【MySQL】深入分析 锁机制(一)行锁 加锁规则 之 等值查询

文章目录前言一、共享锁&#xff08;S&#xff09;和排它锁&#xff08;X&#xff09;二、行锁的3种算法Record LockGap LockNext-key Lock三、加锁规则 之 等值查询分析数据准备3.1 聚集索引有匹配索引无匹配索引3.2 唯一索引有匹配索引无匹配索引3.3 普通索引有匹配索引无匹配…

游戏蓝牙耳机哪个好用?2022超低延迟游戏蓝牙耳机推荐

随着蓝牙耳机的快速发展&#xff0c;使用蓝牙耳机玩游戏的人也越来越多。那么&#xff0c;游戏蓝牙耳机哪个好用呢&#xff1f;当然是延迟越低的蓝牙耳机玩游戏的体验感会越好&#xff0c;我们都知道蓝牙耳机相对于有线耳机来说&#xff0c;或多或少会存在延迟。下面&#xff0…

一文讲解linux SMP Boot

说明&#xff1a; Kernel版本&#xff1a;4.14ARM64处理器&#xff0c;Contex-A53&#xff0c;双核使用工具&#xff1a;Source Insight 3.5&#xff0c; Visio 1. 介绍 SMP, Symmetric Multi-Processor&#xff0c;相对于单核处理器来说&#xff0c;SMP实现了真正严格意义上…

写出这个数

目录 1002:写出这个数 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 代码长度限制 时间限制 内存限制 思路: 1.求和 1.2代码: 2.找到sum的每一位 2.2代码: 3.汉语拼音输出数字 3.2代码: 完整代码: 时间复杂度: 总结: 题…

通过MQ进行系统对接

消息要有来源系统&#xff0c;消息类型&#xff0c;收到消息的应用&#xff0c;通过url取数据。做一个开关&#xff0c;用户可以自己选择方案一和方案二。 方案一&#xff1a;A公司的消息中存json&#xff0c;供应链直接获取json 方案二&#xff1a;通过A公司消息中的UrL&…

Windows系统iis 和多界面怎么安装

Windows系统iis 和多界面怎么安装 服务器拿到手都是有iis&#xff08;iis&#xff1a;用于搭建网站&#xff09;和多界面&#xff08;多界面&#xff1a;用于同时多人操作服务器&#xff09; 但也有服务器是没有安装iis和多界面的&#xff0c;遇到这样的情况就手足无措了。 今…

实训任务5:ZooKeeper节点操作

文章目录一、实训目的二、实训要求三、实训任务四、完成任务&#xff08;一&#xff09;准备工作&#xff08;二&#xff09;实现步骤1、创建Maven项目2、添加相关依赖3、创建日志属性文件4、创建股票价格类&#xff08;1&#xff09;创建init()方法&#xff08;2&#xff09;创…