![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法学习笔记
文章平均质量分 52
观流
这个作者很懒,什么都没留下…
展开
-
位运算相关
位运算最常用的两种操作1.n的二进制表示中第k位是几(个位是第0位)。①先把第k位移到最后一位 n>>k②看个位是几(x&1,如果是1就是1,否则是0)2.lowbit(x)操作:返回x的二进制表示中最靠近右边的一位1以及其之后的数。例:lowbit(1001000)=1000.①如何实现:x&-x(也可以写为x&(~x+1))②原理:在c++里面,一个整数的负数是以补码的形式存在,即x的原码取反加一(~x+1)。比如x=1010....1原创 2022-05-29 18:32:02 · 104 阅读 · 0 评论 -
蒙德里安的梦想
题目描述n×mn×m的棋盘可以摆放不同的1×21×2小方格的种类数。题型状态压缩dp更新2022年5月19日16点36分更新增加适当的空格和换行,愉悦读者体验。带有图示的题解Acwing291. 蒙德里安的梦想:状态压缩dp_阿正的梦工坊的博客-CSDN博客C++ 代码/*下文对 if ((j & k ) == 0 && st[ j | k] ) 有清晰的解释!!!*/#include <bits/stdc++.h>..转载 2022-05-26 22:10:09 · 118 阅读 · 0 评论 -
回形顺序打印
输入一个n行m列的矩阵,从左上角开始将其按回字形的顺序顺时针打印出来#include <iostream>#include <algorithm>using namespace std;int main(){ int n, m; int arr[50][50]; cin >> n >> m; for (int i = 0; i < n; i ++ ) for (int j = 0; .转载 2022-02-10 16:35:17 · 237 阅读 · 0 评论 -
二分法(整数和实数的二分)
是acwing的听课笔记九.二分法(整数和实数的二分)1.整数二分本质:如果有单调性一定可以二分。但是能二分的题目不一定都要二分,所以二分本质并非单调性。如果给定一个区间,可以找到一种区间使得范围能够被一分为二,则可以通过二分法寻找边界。假设左区间为红色,右区间为绿色。【五】给的两个二分模板即对应查找红或绿的情况。红色情况:设定中间值 mid=(l+r+1)/2。mid可以取到边界点//表示检查mid是否满足给定的红色性质,true表示满足,否则falseif(check(m原创 2022-02-10 16:42:09 · 833 阅读 · 0 评论 -
前缀和相关
十一.前缀和一维如果有一个长度为n的数组,前缀和数组Si表示为原数组中前i个数组的和。注意前缀和中下标一定要从1开始。1.如何求Si①用for循环从i=1开始,S[i]=S[i-1]+a[i]2.求Si的作用:可以快速的求出原数组中一段数的和。二维(子矩阵的和)S[i,j]的含义:从第1行到第i行的前j列的和。1.如何去算?一行行的去算。S[i,j]=S[i-1,j]+S[i,j-1]-S[i-1,j-1]+a[i,j]可以画图思考,其中减去的部分是被加了两次的部原创 2022-02-11 19:17:41 · 245 阅读 · 0 评论 -
归并排序算法
七.归并排序(思想也是分治,但是与快排不同归并确定的分界点是整个数组的中心,是下标(即长度 的中心,然后先递归两边,得到左右两个有序数组,最后归并得到一个有序数列。其难点在于最后如何将两个数组合二为一:双指针算法。用两个指针分别指向两个有序的数组,然后再开一个新的数组。比较两个指针指向的元素,将较小者放进数组。直到某一个数组走到尽头,就把另一个数组剩下的数都补进新开的数组里。当上下两个指针指向的数都一样时,一般将上一个数放进数组。#include<iostream>usin原创 2022-02-10 16:38:47 · 156 阅读 · 0 评论 -
逆序对的数量
八.逆序对的数量当前一个数比后一个数严格大(即不会相同)的时候,就称两个数为逆序对也用到了分治的思想。首先看归并的基本思想:1.将整个区间一分为二。[L,R]=>[L,mid],[mid+1,R]2.递归处理两个子区间3.归并两个序列然后将所有可能存在的逆序对视为三大类。1.两个数同时出现在左区间2.同时出现在右半边3.一个左一个右。接下来分情况讨论(假设归并的同时能统计三种情况,则逆序对数量为三种情况的数量之和:1.第一种情况:左半边内部逆序对数量,其个数应为me原创 2022-02-10 16:39:45 · 1072 阅读 · 7 评论 -
快速排序算法
一.快速排序1.随机确定一个分界点作为x2.调整范围:把比x小的数字放到x左边,比x大的放x右边,用两个指针来实现,先用i 指针从左边第一个数开始移动,直到碰到比x大的停止,再把指向右边第一个数的j 指针向中间移动,直到碰到比x小的停止,然后把i和j指向的数交换,交换完后两个 指针向中间移一位3.递归对两边进行排序#include <iostream>using namespace std;const int N=1e6+10;int n;int q[N];voi原创 2022-02-10 16:24:38 · 169 阅读 · 0 评论 -
快速选择算法
六.快速选择算法(在一个数组里查找第k小的数字在一个数组里实现快速选择。首先执行快速排序的前两步,得到以分界点为界的左右两个区间,然后比较左区间中数的个数与k的大小,如果小,说明第k小的数在左区间里面,反之则在右区间里面,此时只要对左区间或者右区间进行递归快速排序即可。#include<iostream>using namespace std;const int N=100010;int n,k;ing q[N];intquick_sort(int l,int .原创 2022-02-10 16:37:59 · 193 阅读 · 0 评论 -
高精度计算
十.高精度(大整数每一位存到数组里,第一个存个位)可视为模拟人工计算的过程1.高精度加法A+B(两个大整数相加,位数一般是1e6)其实是模拟人工加法的过程。用t表示相加的进位。#include<iostream>#include<vector>using namespace std;const int N=1e6+10; vector<int> add(vector<int> &A,vector<int>原创 2022-02-10 16:43:19 · 382 阅读 · 0 评论 -
反转字符串
四.反转字符串给出一个字符串并输入n,要求将n个字符放到原本字符串后面第一时间想到的做法基本都是,循环内读取前n个字符一一加到后面然后删除前面,但是这样涉及到的时间复杂度是O(n),所以有更好的做法可以优化到时间O(1)空间O(n)即先整体反转,再将前size-n个字符和后面n个字符看做两部分分别反转class Solution{ public: string leftRotateString(string str,int n){ revers原创 2022-02-10 16:36:42 · 121 阅读 · 0 评论 -
记忆化搜索
给定一个 RR 行 CC 列的矩阵,表示一个矩形网格滑雪场。矩阵中第 ii 行第 jj 列的点表示滑雪场的第 ii 行第 jj 列区域的高度。一个人从滑雪场中的某个区域内出发,每次可以向上下左右任意一个方向滑动一个单位距离。当然,一个人能够滑动到某相邻区域的前提是该区域的高度低于自己目前所在区域的高度。下面给出一个矩阵作为例子:1 2 3 4 516 17 18 19 615 24 25 20 714 23 22 21 813 12 11 10 9...原创 2022-05-26 21:02:57 · 72 阅读 · 0 评论 -
区间DP相关
1.石子合并设有 NN 堆石子排成一排,其编号为 1,2,3,…,N1,2,3,…,N。每堆石子有一定的质量,可以用一个整数来描述,现在要将这 NN 堆石子合并成为一堆。每次只能合并相邻的两堆,合并的代价为这两堆石子的质量之和,合并后与这两堆石子相邻的石子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同。例如有 44 堆石子分别为 1 3 5 2, 我们可以先合并 1、21、2 堆,代价为 44,得到 4 5 2, 又合并 1,21,2 堆,代价为 99,得到 9 2 ,再合并原创 2022-05-26 21:01:22 · 55 阅读 · 0 评论 -
一些线性DP
闫式DP法,尝试用集合来表示状态。1.数字三角形给定一个如下图所示的数字三角形,从顶部出发,在每一节点可以选择移动至左下方或者右下方,一直走到底。要求找出一条路径,使得路径上的数字和最大。用暴搜会超时。使用DP时,我们需要寻找变化的点并且把它表示出来。这里我们选择从下往上的路线行走,那么对于每个节点,他的不同在于是从他的左下方来到他本身还是从右下方。用二维坐标来表示的话,到达(i,j)的方法有两种,从(i+1,j)或者(i+1,j+1),我们只要取其中较大者即可。.原创 2022-05-26 21:00:11 · 97 阅读 · 0 评论 -
一些背包问题
三十二.01背包问题动态规划算法(DP)_那什-CSDN博客_dp算法这里是动态规划算法的一篇博客,讲得比较基础而且容易理解。其实我之前理解一直有误,这里换一种说法解释一下方便理解。f[i][j]指的是在有i件物品和j容量的情况下。这里一定要注意j表示的不是当前的剩余容量而是当前总的容量是多少!由此可得当状态转移时,f[i-1][j-w[i]]指的是当有i-1件物品时容量为j-w[i]的情况,也是在当时情况下取得的最大价值!在二维数组dp的方法中进行初始化,一开始只有f[0][0]是合法原创 2022-02-10 16:31:20 · 574 阅读 · 0 评论 -
一点点图论相关(二)
1.spfa算法SPFA算法_善思的博客-CSDN博客_spfa算法3.Floyd算法求多源最短路。用邻接矩阵把图存下来,然后三重循环。第一重循环,k从1到n,第二重循环i从1到n,第三重循环j从1到n。每次更新一遍。d[i][j]=min(d[i][j],d[i][k]+d[k][j]);循环之后,di存的就是从i到j的最短路径长度,原理基于动态规划。d[k,i,j]表示从i出发,只经过1~k这些中间点到达j的最短距离。循环中首先枚举k,因为k表示阶段3.Prim算法求最小原创 2022-05-26 20:53:14 · 254 阅读 · 0 评论 -
树与图的深度、广度优先遍历
二十二.树与图的深度遍历从一个起点出发一条路遍历到黑,如果到头了就回溯检查是否找过了所有的路,没有就从分叉口继续走。//基本框架int h[N],e[M],ne[M],idx;bool st[N];void dfs(int u){ st[u]=true;//标记一下已经被搜索过了 for(int i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(!st[j]) dfs(j); }}给定...原创 2022-02-11 19:28:19 · 244 阅读 · 0 评论 -
一点点图论相关(一)
一.有向图的拓扑序列就是图的宽度优先遍历的应用。什么是拓扑序列?如果一个点的序列满足对于图中的每条有向边xy(x、y是两个点),x都出现在y的前面(即起点都在终点前面),便称该序列为拓扑序列。一个有向无环图一定存在拓扑序列。这种图又称拓扑图。有向图中每个点有两个度。入度:有多少条边指向自己。出度:自己延伸出多少条边指出去。所以所有入度为0的点都可以作为起点。把它们入队。然后进行宽搜二.Dijkstra求最短路(一定不能存在负权边)1.朴素版:1.首先初始化距离dis[1]=0原创 2022-05-26 20:48:21 · 497 阅读 · 0 评论