算法进阶指南
主要使用C/C++语言来解决一些算法竞赛中的问题,来互相交流。
宅男小付
这个作者很懒,什么都没留下…
展开
-
0x08总结和练习
题目一:飞行员兄弟“飞行员兄弟”这个游戏,需要玩家顺利的打开一个拥有16个把手的冰箱。已知每个把手可以处于以下两种状态之一:打开或关闭。只有当所有把手都打开时,冰箱才会打开。把手可以表示为一个4х4的矩阵,您可以改变任何一个位置[i,j]上把手的状态。但是,这也会使得第i行和第j列上的所有把手的状态也随着改变。请你求出打开冰箱所需的切换把手的次数最小值是多少。输入格式输入一共包含四行,每行包含四个把手的初始状态。符号“+”表示把手处于闭合状态,而符号“-”表示把手处于打开状态。至少一个手原创 2020-09-13 13:00:17 · 1034 阅读 · 0 评论 -
0x07贪心
贪心:贪心是一种在每次决策时采取当前意义下最优策略的算法,因此,使用贪心法要求问题的整体最优性可以由局部最优性导出。贪心算法的正确性需要证明,常用的证明方法有:1.微扰(邻项交换)证明在任意局面下,任何对局部最优策略的微小改变都会造成整体结果变差。经常用于以“排序”为贪心策略的证明。2.范围缩放证明任何对局部最优策略作用范围的扩展都不会造成整体结果变差。3.决策包容性证明在任意局面下,作出局部最优决策以后,在问题状态空间中的可达集合包含了作出其他任何决策后可达的集合。换言之,这个局部最优策略提供原创 2020-09-10 08:22:14 · 208 阅读 · 0 评论 -
0x06倍增
倍增,字面意思就是“成倍增长”。这是指我们在进行递推时,如果状态空间很大,通常的线性递推无法满足时间与空间复杂度的要求,那么我们可以通过成倍增长的方式,只递推状态空间中在2的整数次幂位置上的值作为代表。当需要其他位置的值时,我们通过“任意整数可以表示成若干个2的次幂项的和”这一性质,使用之前求出的代表值拼成所需的值。所以使用倍增算法也要求我们递推的问题的状态空间关于2的次幂具有可划分性。试想这样一个问题:给定一个长度为N的数列A,然后进行若干次询问,每次给定一个整数T,求出最大的K,满足A[I]+A[2]原创 2020-09-04 11:08:51 · 256 阅读 · 0 评论 -
0x05排序
我们通常会用到以下这些排序算法:1.选择排序,插入排序,冒泡排序2.堆排序,归并排序,快速排序3.计数排序,基数排序,桶排序前两类是基于比较的排序算法,对n个元素进行排序时,若元素比较大小的时间复杂度为0(1),则第一类排序算法的时间复杂度为0(n^2),第二类排序算法的时间复杂度为0(nlogn)。实际上,基于比较的排序算法的时间复杂度下界为0(nlogn),因此堆排序,归并排序与快速排序已经是时间复杂度最优的基于比较的排序算法。第三类算法换了一种思路,它们不直接比较大小,而是对排序的数值采取按原创 2020-09-04 11:08:25 · 311 阅读 · 0 评论 -
0x04二分
二分:一般二分的基础用法是在单调序列或单调函数中进行查找。因此当问题的答案具有单调性时,就可能通过二分把求解转化为判定。整数二分:下面的二分的写法保证最终答案处于闭区间[l,r]之内,循环以l=r结束,每次二分的中间值mid会归属于左半段与右半段二者之一。在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继)while(l<r){ int mid = (l+r)>>1; if(a[mid]>=x) r = mid else l = mid+1;}retu原创 2020-09-02 09:30:05 · 319 阅读 · 0 评论 -
0x03前缀和与差分
前缀和:原创 2020-08-20 13:24:39 · 483 阅读 · 0 评论 -
0x02递推与递归
递推:以已知的“”原创 2020-08-18 20:01:48 · 163 阅读 · 0 评论 -
0x01 位运算
一些常用的类型的大概范围4个字节的int类型大概在21亿左右(-2147483648~2147483647)即-2^31到(2^31)-1。当任意两个数值做加减法运算,都等价于在32位补码下做高位不进位的二进制加减法运算,发生算术溢出时,32位无符号整数相当于对2^32取模,这也解释了有符号整数算术上溢时出现负数的现象。0x3f3f3f3f是一个很有用的数值。它是满足以下两个条件的最大整数1.整数的两倍不超过0x7f ff ff ff(0111……111),即int能表示的最大整数。2.整数的每8原创 2020-08-13 14:57:50 · 2239 阅读 · 0 评论