算法(基础)
文章平均质量分 96
/
山上一缕烟
这个作者很懒,什么都没留下…
展开
-
使用深度优先搜索(DFS)、广度优先搜索(BFS)、A* 搜索算法求解 (n^2 -1) 数码难题,耗时与内存占用(时空复杂度)对比(附:(n^2 - 1) 数码问题控制台简易演示程序)
一、实验目的通过编程实验,体会并理解人工智能领域常用的新型搜索算法的测试用例 —— (n^2 -1) 数码问题。二、实验内容和要求通过深度优先搜索(DFS)、宽度优先搜索(BFS)、A*搜索算法来求解 (n^2 -1) 数码难题,要求如下:初始状态以及目标状态形如下图。输出完整的从初始状态到目标状态的动作序列。对比3种算法的时间、空间消耗。三、参考实验环境CPU: Intel Core i5-8400 @ 2.80 GHz / 3.80 GHz, 6C6T 指令集: MMX原创 2021-05-17 10:53:40 · 1445 阅读 · 0 评论 -
【说人话的算法小课堂】DP 求解 01 背包问题(在总重恰好为背包容量 W 的条件下)
01背包问题设有n个物品,其重量(或占用空间)分别为w_1,w_2,…,w_n,价值分别为v_1,v_2,…,v_n。给定一个总容量为W的背包,每个物品只能整个放入背包或不放。问:如何选择放入背包的物品,使得背包中的物品的总重恰好为W的同时,总价值最大?解法动态规划(DP)。将决策过程分成n个阶段,每个阶段考察1个物品是否选择。决定是否选择某物品,要根据在其它条件不变、背包容量更小时是否选择来决定。依次考察物品1到n。当考察物品i时,意味着前i个物品是否选择已经决定完毕。如不选物品1,则.原创 2020-12-23 22:15:34 · 259 阅读 · 0 评论 -
【说人话的算法小课堂】求两个序列的最长公共子序列长度,并给出符合条件的任意一个解(DP)
最长公共子序列对一个序列X=(x_0,x_1,…,x_(m-1) ),若序列Y=(y_0,y_1,…,y_(k-1) ),当存在一个严格递增的下标序列(i_0,i_1,…,i_(k-1) ),使得∀j∈[0,k-1], j∈Z,都有x_(i_j )=y_j,则序列Y是序列X的子序列。显然,子序列可由原序列去掉若干项(可以一个也不去掉)得到。若序列Z是A和B的子序列,则称Z是A, B的公共子序列。当Z含有的项数最多时,称Z为A, B的最长公共子序列(longest common subse.原创 2020-12-14 20:23:07 · 1030 阅读 · 0 评论 -
【说人话的算法小课堂】贪心法-活动安排问题(正确性证明)
活动安排问题设有n个活动,编号分别为1,…,n。每个活动进行期间都始终需要占用某个物品(资源)。活动k的起始和结束时间分别为b_k,e_k,它们均为非负整数。一旦活动开始,就不允许被中断,直至活动结束。要求给出活动安排方案,使得能进行的活动数量最多。如果有多个最优解,输出任意一个。解法【1】将各个活动{a_n }按结束时间升序排序。【2】设E为已选取的最后一个活动的结束时间,其初值为E=0。【3】从排序后的第一个活动开始,循环如下部分:对第i个活动:【3.1】如果该活动的开始时间b_i.原创 2020-12-03 21:50:35 · 2838 阅读 · 0 评论 -
【说人话的算法小课堂】按字典序升序枚举n个元素的所有全排列(算法步骤 + 正确性证明)
全排列定义从n个元素中取出全部的n个进行排列,就得到全排列。算法:按字典序升序枚举n个元素的所有全排列设集合{a_1,a_2,…,a_n}的一个全排列为P=p_1,p_2,…,p_(j-1),p_j,p_(j+1),…,p_n。【1】从排列的右端开始,找出第一个比右边数字小的数字的序号j。即:令i=n-1,n-2,…当第一次满足p_i<p_(i+1)时,停止,并记j=i。如果没有找到符合条件的i,意味着整个排列的字典序已经最大,算法结束。【2】在p_j右边的数字中,找出所有比p_j大原创 2020-10-23 08:38:45 · 633 阅读 · 0 评论 -
【说人话的算法小课堂】连续子数列的最大和(O(n^2)解法、O(n log n)解法、O(n)解法)
O(n^2)解法枚举长为n的数列a的全部的连续子数列a[i,j]:分别枚举起点i和终点j,但在枚举终点j=i,i+1,…,n的同时可以根据数列前n项和、前n-1项和与第n项的关系S_n=S_(n-1)+a_n累加子数列a[i,j]的和。共两重循环,代码如下:template<class T> T max_sub_sum(const T* const a, size_t n) { T sm = 0, s; for (size_t i = 1; i <= n; ++i) { .原创 2020-10-19 21:52:09 · 294 阅读 · 0 评论 -
【说人话的算法小课堂】使用分治法(基于归并排序的思想)求一个排列的逆序数(O(n^2)→O(n log n))
分治法求逆序数前置知识:归并排序。我们已经证明了归并排序的正确性。只要将归并排序算法作少量修改,就可以将求一个排列的逆序数的时间复杂度从O(n^2)降低到O(n logn)。将一个排列P尽量均匀地分成两部分P_1,P_2。则P的逆序数τ§=τ(P_1 )+τ(P_2 )+τ_Merge显然,τ(P_1 )和τ(P_2 )分别代表递归求解的在P_1,P_2范围内的逆序数。而τ_Merge则将遗漏的情况,即构成逆序对(a_i,a_j), i<j, a_i>a_j的两个元素a_i.原创 2020-10-10 22:57:16 · 304 阅读 · 0 评论 -
【说人话的算法小课堂】使用分治法求最大连续子序列的和
使用分治法求最大连续子序列的和设有一个整数数列a[n],1≤s, t≤n。求a[n]的一个子数列a[s, t],使得该子数列的和尽可能大。若这个和小于0,则输出0。【算法本体】(参考代码中,因为要与暴力法对比运行时间,而暴力法用到前缀和,为了方便,数组下标从1开始)设m = floor((s + t) / 2)。当n = 1时,直接取唯一的元素作为结果。若该元素为负,则输出0。当n > 1时,分3种情况讨论:【情况1】该子数列完全落在原数列的左半部分a[s, m]。递归对数列a[s,原创 2020-09-20 11:56:29 · 984 阅读 · 0 评论 -
【说人话的算法小课堂】查找一个数列的第 k 小元素
第k小元素【算法过程】借助快速排序的划分操作的过程。由于每一趟快速排序都会将枢轴(默认取数组的第一个元素)置于数组中的某个位置,且左边和右边的元素都分别比枢轴本身小或大(假设升序排序)。所以,得到如下的过程:【1】在完成一趟快速排序后,判断枢轴在数组中的新位置。因为数组下标是0开始的,所以如果枢轴的下标i = k – 1,那么枢轴即为第k小的元素。【2】如果枢轴的下标i < k – 1,那么第k小的元素在枢轴右侧,对右侧递归查找。【3】如果枢轴的下标i > k – 1,那么第k小的元素原创 2020-09-20 11:51:02 · 324 阅读 · 0 评论 -
【说人话的算法小课堂】归并排序的正确性证明及时间复杂度分析(2020/9/25修订)
template<class _Ty> void merge(_Ty* _begin, _Ty* _mid, _Ty* _end) { const auto l = _end - _begin + 1; _Ty* t = new _Ty[l], * i = _begin, * j = _mid + 1, * k = t; while (i <= _mid && j <= _end) { if (*i <= *j) { *k = *i; ++i; ++k原创 2020-09-14 00:04:16 · 1050 阅读 · 0 评论 -
【说人话的算法小课堂】快速排序的正确性证明及时间复杂度分析
快排代码:template<class _Ty> _Ty* partition(_Ty* _begin, _Ty* _end) { _Ty* i = _begin, * j = _end, t = *_begin; while (i != j) { while (j > i && *j >= t)--j; *i = *j; while (i < j && *i <= t)++i; *j = *i; } *i = t原创 2020-09-14 00:00:17 · 1555 阅读 · 0 评论 -
【说人话的算法小课堂】N 皇后问题(C++ 实现)
N皇后问题把n个皇后放在n×n的国际象棋棋盘的格子上,要求任意两个皇后不能处于同一条水平线、垂直线或对角线。给出任意一个可行解。算法:设横纵坐标的范围都是离散闭区间[0,n – 1]。先确定每个皇后的横坐标。这里通过随机方法确定,将离散闭区间[0,n – 1]的整数打乱顺序并放入一个数组。按顺序访问这个数组,尝试放置每个皇后于指定的横坐标。尝试放置第i个皇后时,纵坐标也用同样的方法随机确定。尝试放置后,先进行检查,考察是否有任意两个皇后的摆放位置不符合要求。如果都符合,则尝试摆放第(i + 1)个原创 2020-06-17 11:54:45 · 735 阅读 · 0 评论