算法基础课笔记
文章平均质量分 83
断线纸鸢s
这个作者很懒,什么都没留下…
展开
-
01背包
动态规划 (01背包模型)1、基本的背包模型2、动态规划的理解方式通常可以将 动态规划(DP) 问题分为两个部分进行理解:1. 状态表示。2. 状态计算2.1状态表示(抽象点)背包模型,可以表示成二维的一个表示在哪几个物品里面选一个表示背包的体积多少如: dp[i][j] 其中的 i 表示为从i个物品中选择。j表示选择的物品的题解不超过j动态规划需要用到的数据结构是数组,用来记忆之前的属性从而推出下一个的属性的过程。用数组的下标,记录当前的状态,一个状态表示的是当前状态所约束下的集原创 2021-04-12 23:14:15 · 106 阅读 · 0 评论 -
模拟队列
模拟队列变量解释:t指向尾指针,h指向头指针初始化的时候h要比t大1,因为第一个插入(只有一个元素)的时候h和t应该指向同一个位置代码:#include<iostream>using namespace std;const int N = 100010;//初始化的时候尾要比头少1,当h = t 的时候只有一个元素,当h > t 的时候为空int h=1,t,que[N];int main(){ int M; cin>>M; w原创 2020-10-08 19:47:47 · 100 阅读 · 0 评论 -
模拟栈
模拟栈用数组模拟栈,只需要维护一个指针,因为栈的数据是单方向进入的,所以只需要维护一个指针。入栈:stk[++head] = x;出栈:head–查询栈顶元素:stk[head]判断是否为空if(!head)#include<iostream>using namespace std;const int N = 100010;int head,stk[N];void push(int x){ stk[++head] = x;}void pop()原创 2020-10-08 19:47:14 · 104 阅读 · 0 评论 -
双向链表
双向链表双向链表数据结构具有前后指针的链表结构题目链接https://www.acwing.com/problem/content/829/操作分析注意: 插入操作默认是从k的后面插入0 和 1 是左右边界,不是具体的值0是左边界, 1 是右边界以idx == 1 为结束条件代码:#include<iostream>using namespace std;const int N = 100010;int idx,e[N],L[N],R[N];void ini原创 2020-10-08 17:44:56 · 160 阅读 · 0 评论 -
模拟单链表
单链表单链表:只有数值跟后指针的数据结构题目地址:https://www.acwing.com/problem/content/828/变量表示:head : 头指针,始终只想链表的头节点e[N] : 数值数组,存放每个节点数值,下标表示存储地址,存放的值为节点的值ne[N] : 指针数组,存放每个节点的指针,下标表示当前节点的存储地址,存放的值是下个节点的地址idx : 地址,分配的地址,就是各个数组的下标,相当于内存中的0x3fde..之类的。这边的数组相当于为这个链表分配的存储空间原创 2020-10-08 16:30:34 · 95 阅读 · 0 评论 -
高精度减法
高精度减法题目链接https://www.acwing.com/problem/content/794/步骤对大数的处理仍然是用vector<int> 数组进行存储判断哪个数大(始终用大的那个数减去小的那个数,如果是负数,就在结果前面添加负号)如果位数不相等,则位数大的数大如果位数相等,从大的位数开始比较,大的大,如果循环结束则相等相减操作,从低位开始减,不够的借位,t表示是否想前面借位先减去t表示先减掉借位的数t = A[i] - t;然后判断:如果当前位数小于B的原创 2020-09-23 16:41:02 · 107 阅读 · 0 评论 -
递归实现指数型枚举
递归实现指数型枚举做题思路创建一个空间存储要便利的个数状态如要枚举3个数的所有排列组合,那要创建三个空间,来存储每个数的状态开始枚举要枚举三个数的所有组合,那么就要便利所有的情况,那么每一个数都有选和不选两种情况所以每一个数都要分两种情况进行递归最后终止的条件是枚举的个数不超过三个(三个数进行枚举,可选可不选,所以所选择的个数可以是1~3个)理解采用递归的思路,就是:看要枚举几个数,几个数他递归的层数就是几层因为每个数只有选和不选两种情况,所以他的分支只有两个,是一个二叉原创 2020-09-23 16:40:31 · 179 阅读 · 0 评论 -
高精度加法
高精度加法题目链接https://www.acwing.com/problem/content/793/思路输入的时候使用字符串string存储将char类型转换成int类型,使用vector<int> 逆序存储模拟手算加法的过程判断位数,循环最大位数定义一个累加器 t每一次循环t += A[i]因为A始终是最大位数,但是在累加B[i]的时候要判断当前位数是否小于B的位数,如果小于才相加。每次结果都取 t%10,并且t /= 10 如果t大于时则t原创 2020-09-23 16:41:14 · 112 阅读 · 0 评论 -
高精度除法
高精度除法原题链接https://www.acwing.com/problem/content/796/步骤倒序用vector 存储大数定义一个int r用于存储余数用引用r做参数,函数里面可以修改r的值模拟除法先判断当前位数上的数够不够除如果够直接除,并取模除下一个如果不够在原本数的基础上乘以10 再加上下一位数变成实现除法操作:累加器(余数r)初始化为0,所以一开始就r = r * 10 + A[i]因为如果不够除当前位数上的值为0,所以不管够不够除直原创 2020-09-22 17:17:33 · 92 阅读 · 0 评论 -
子矩阵的和
子矩阵和原题链接https://www.acwing.com/problem/content/798/作用快速求某一矩阵区间的和公式子矩阵前缀和公式s[i][j] += (s[i-1][j] + s[i][j-1] - s[i-1][j-1])子矩阵和公式res = s[x2][y2] - s[x1-1][y2] - s[x2][y1-1] + s[x1-1][y1-1]注意点左上方的那个点上的数也包括,所以公式上面的x1,y1都要减一代码#include<iostre原创 2020-09-22 17:17:03 · 252 阅读 · 0 评论 -
完全背包
完全背包完全背包:每个物品有无限表,表示每新增一个物品可以选取无限次。思维导图完全背包跟01背包的区别:相同点:将集合划分成两部分:未包含新增物品i 的集合 (已知f[i-1][j])包含新增物品i 的集合**(新增,未知)**求集合的最大值的方式相同:分别求出两部分集合的最大值,再求这两个最大值的最大值求新增的集合最大值的方式相同:对背包容量进行划分第一部分:划分出所有选法中共同拥有的物品(新增物品)第二部分:剩下的都是不一样的物品新增集合的最大值 = 第一部分的最原创 2020-09-22 17:16:36 · 150 阅读 · 0 评论 -
前缀和
前缀和原题链接https://www.acwing.com/problem/content/797/作用可以快速求某一个区间的和公式初始化前缀和s[i] = s[i-1] + a[i]**求某一段区间的和[l,r] **s[r] - s[l-1]注意点在初始化前缀和以及输入的时候,数组使用1开始可以解决边界问题并且后面求区间的时候也可以直接套用公式代码#include<iostream>using namespace std;const int N =原创 2020-09-22 17:15:23 · 95 阅读 · 0 评论 -
快排
快排原题链接思路想法:取一个分界值,然后将当前序列按照这个值,分成两个部分,一个部分是小于这个值的,一部分是大于这个值的这个时候已经将一个乱序的序列分成了两个部分,然后同时再对这两个部分同样进行相同的排序操作依次递归下去,直到只剩一个数的时候就不用遍历了,这时候所有的数都已经排列好了实现步骤:设置递归停止条件:if(l >= r)return;这个是停止的条件,就是当需要排序的时候这时只有一个数,所以并不需要排序,直接结束定义一个分界线mid(值):int mid = a[原创 2020-09-22 17:14:52 · 150 阅读 · 0 评论 -
归并排序
归并排序题目链接https://www.acwing.com/problem/content/789/思路归并排序也是使用递归,不过其思路更好理解一点,因为理解起来不用理解那么细致。我们按照中间的位置将这个序列分成两个部分,并分别进行排序,这时候这个序列是由两个有序的序列组合起来的然后只要将这个两个序列合并成一个序列就完成了。所以,归并排序就是将一个乱序的序列,分成两个有序的序列再将其合并起来!步骤同样这是个递归,要设置终止条件if(l >= r) return;定义从哪个点原创 2020-09-22 17:14:21 · 160 阅读 · 0 评论 -
高精度乘法
高精度乘法原题链接https://www.acwing.com/problem/content/795/步骤倒序,用vector存储大数模拟手动乘法将乘数看成一个整体(一位数)每次相乘哪一位就加上前一位相乘所得的值模10取得当前这位的值除10 表示当前位的数已经取了去除前位零注意存在乘完大数的最后一位,但是仍有进位的情况,所以总之条件不仅仅是i < A.size()而是i < A.size() || t t 表示: 累加器去除前位零代码:#inc原创 2020-09-22 17:13:49 · 91 阅读 · 0 评论 -
二分查找
二分查找整数二分https://www.acwing.com/problem/content/791/思路思路跟平时猜价格的游戏差不多,给你一个商品,再给你一个范围,让你从这个范围里面猜价格每次都选择这个范围的中点,然后判断价格是比中点大还是比中点小,然后再根据这个判断结果缩小范围,以此类推最后剩下一个数的时候肯定就是答案步骤先定义范围int l = 0,r = n-1;然后开始二分(进入循环),寻找中间点int mid = l + r >> 1;进行判断,根据判断改变范围i原创 2020-09-22 17:13:19 · 101 阅读 · 0 评论 -
差分
差分矩阵原题链接https://www.acwing.com/problem/content/800/初始化的公式差分跟前缀和的关系,差分是前缀和的逆运算前缀和是将原本所有的数列都当成是一堆差分,然后对其进行求前缀和差分是将原本所有的数列每一个数都当成一个前缀和,然后求他们的差分而他们所使用的公式是一样的,只是所求的变量是不一样的,前缀和是根据原数列的数求前缀和,而现在是根据前缀和求原数列的数差分矩阵初始化公式由上图的前缀和公式可得,s[x][y] = (s[x][y-1] - s[x-原创 2020-09-22 17:12:42 · 117 阅读 · 0 评论 -
01背包
动态规划 (01背包模型)1、基本的背包模型2、动态规划的理解方式2.1状态表示部分(抽象点)背包模型基本表示成二维的:一个表示在哪几个物品里面选一个表示背包的体积多少动态规划需要用到的数据结构是数组,用来记忆之前的属性推出下一个的属性的过程用数组的下标,记录当前的状态,一个状态表示的是当前状态所约束下的集合,属性:数组的值表示的是属性属性有最大值最小值,和数量等,属性是指当前状态下集合的属性,是基于当前状态的基础上的属性正如上面所说,集合是受状态约束的,约束的变量是数组的原创 2020-09-22 17:12:18 · 148 阅读 · 0 评论