![](https://img-blog.csdnimg.cn/20201014180756918.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法
文章平均质量分 90
小胡不糊
和光同尘
展开
-
状态压缩动态规划—(附luogu官方题单解法
状态压缩动态规划—(附luogu官方题单解法状态压缩,即将状态通过二进制存储,以将一个复杂的状态仅仅用一个int数字表示。在动态规划中,有着很多状态的转化,面对一些不是那么复杂的题目,我们很容易使用一维数组二维数组或三维数组的下标来存储状态,但是如果状态很复杂有着三维甚至三维以上,再仅仅使用数组下表存储就有些不合适了,下面是luogu状态压缩及动态规划官方题单题单链接由简到难列出了几道状态压缩动态规划题的解法及思路一、P1433P1433 这道题一开始看是没什么思路的,有点复杂,对着别人题原创 2021-09-15 16:16:45 · 219 阅读 · 0 评论 -
AC自动机
Ac自动机就是在一个字符串中,查找多个给出多个模式串,查找匹配。多次kmp字符串匹配?在给出模式串数目特别大的情况下,即便是kmp也运行不了,因此,我们这里有了ac自动机,即在tire上kmp,只需遍历一遍原字符串就能找出所有匹配。tire树又称字典树,利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较 详解(我们需要在trie上kmp。首先是建立一个...原创 2020-12-25 11:56:19 · 125 阅读 · 2 评论 -
P2440 木材加工————二分答案
P2440 木材加工一题二分答案,但是又有不同,我们之前要求的是求给定切割的数目求最大值,这里要求的是,给定最小切割次数,求最大值。因此我们只需要在二分的地方修改一下。易知:小于l的值都满足,因此,最后输出r即可。#include<stdio.h>#include<stdlib.h>#define size 1000050int all[size];int main() { int n, k, i; int l = 1, r = 1; scanf("%d%d",原创 2020-12-23 10:14:41 · 299 阅读 · 0 评论 -
P1233 木棍加工————洛谷 动态规划
P1233 木棍加工这道题要求,寻找的x,y,递减链的最少数目。由于没有排序,先按照x排个序(x相等时,按照y排序)这样就能由二维降到一维。这样问题就变成,在排好序的序列中,寻找按照y递减的链的最少数目。这里有一个定理,对于一个偏序问题,它的最少递增链的数目,等于最长递减子序列的长度。于是题目就变成了寻找最长递增子序列。还不会?动态规划————模板最长递增/公共子序列#include<stdio.h>#include<stdlib.h>#define size 500原创 2020-12-20 16:29:21 · 319 阅读 · 0 评论 -
动态规划————模板最长递增/公共子序列
P1439 【模板】最长公共子序列先来说说最长递增子序列的解法,最长递增子序列,即一个序列中递增序列最大长度。对于长度为 n 的序列,它的最长递增子序列有三种情况长度为n-1的前缀的最长子序列 加上再加上最后一个元素长度为n-1的前缀的最长子序列长度为n-1的前缀的最长子序列的最后一个元素替换为最后一个元素前两点易于理解,最后一点即为寻找最优子结构的贪心过程。对于长度相同的递增序列,我们当然是要最后一个元素的值越小越好。因此,我们可以从长度为1的序列开始,每次插入一个元素,更新长度为k原创 2020-12-19 11:18:16 · 135 阅读 · 1 评论 -
快速排序手写优化版本(防特殊数据)————o(nlogn)寻找第k大数
快速排序:快速排序相较于其他排序算法是最快的,因为无论是最好情况还是最差情况,在优化后时间复杂度都能达到o(nlogn),而且不需要额外的空间,唯一的缺点就是不是稳定的。原理:对于给定的待排序的序列,任取一个元素作为基准数,再将当前序列中小于该数的放到前面,大于该数的放到该数后面,找到该数的位置,最后递归求解两子序列。C语言实现:int cmp(int element1,int element2){//比较 return element1-element2;}void swap(size_t原创 2020-10-22 22:03:37 · 192 阅读 · 1 评论 -
P1966 火柴排队————洛谷 动态规划
P1966 火柴排队这一题可以看成是逆序对问题的应用(逆序对问题)首先,我们可以知道当所有高度最小的时候,有两个序列中第k大的元素刚好配对,这里就不给出证明了。然后呢,我们通过对下标(将下标所对应的值作为关键字)的排序,再分别将两个数组的下标匹配,,其中的逆序对个数极为所求的最小的移动次数。#include<stdio.h>#include<stdlib.h>#define size 500005int mod = 1e8 - 3;int tmp[size], a原创 2020-12-17 17:09:02 · 190 阅读 · 0 评论 -
逆序对个数问题————分治(超简短代码)
P1908 逆序对逆序对:在一个元素序列中有,a[i]>a[j],而i<j,则称这两个元素为一个逆序对。逆序对使用分治的方法解决,相当于是进行一次递归排序(不懂的点这里),因此时间复杂度为o(nlogn)。在对一个序列两个已排好序的子序列进行合并时,有两种情况再这里用a[i],a[j]分别表示两个序列中的元素,l,mid,r 表示序列原序列最左,中间,最右下标。a[i]<=a[j],则待加入元素,与未加入元素之间没有逆序对。a[i]>a[j],则a[j]加入序列,a[j原创 2020-12-17 16:06:04 · 1841 阅读 · 0 评论 -
KMP算法代码模板,c语言实现,附有题目
网上有很多kmp算法的博客,看了好久都没有弄懂,于是就自己写一篇。首先我们需要明确几个定义:前缀:字符串前面的一段后缀:字符串后面的一段kmp算法思想:寻找一个字符串的,前缀与后缀的最大匹配,该前缀后缀不能为它自身。在朴素字符串匹配中,若某一点不匹配,则需要从头开始,这中间会做了有很多不必要的工作。我们找到已匹配字符串段的后缀的最大前缀匹配,再将该前缀作为已匹配字符串往后遍历。由于找到的是后缀的最大前缀匹配,因此可以保证不会有遗漏。#include<stdio.h>#inclu原创 2020-12-13 10:38:20 · 230 阅读 · 0 评论 -
链式前向星原理以及具体实现(看这一篇就够了!!!)
链式前向星是什么?图的一种存储方式。有什么用?简化版的邻接链表的存储。链式前向星就是存储图中的每条边,但是,有几个额外的数组,可以用于在很短时间内查找(**类似邻接表)**到以某一点为起点的边。那么为什么要这个写这个呢?他简单啊。对,就是这样。————————————————————首先,我们需要两个数组edge,var(当然你也可以用结构体)来分别存新加入边的权重和终点。同时为了能够遍历以某一节为起点的所有边,我们还需要两个数组~~(精髓来了)~~ ,next[i],head[i],分别用来存储原创 2020-12-12 17:01:15 · 714 阅读 · 0 评论 -
Bellman Ford
可以有负环。遍历每一条边n-1次,同时更新dis(若无负环则最短路径长度不超过n-1)#include<stdio.h>#include<stdlib.h>#define size 100000#define sup 0Xffffff0struct edge { int u; int v; int w;};typedef struct edge edge;//边edge all[size];int cnt, dis[size];void insert(in原创 2020-12-09 11:55:40 · 76 阅读 · 0 评论 -
背包问题模板 组合背包(普通背包问题,完全背包,多重背包)
背包问题大部分都是模板题,这里整理了组合背包的模板。组合背包:物品的可取数目为1,有限个或无限个。也就是说该模板适用于01背包,完全背包,多重背包———————————————————————对于可取数目不为一的处理思路:我们将该物品的数目,分解成几个2的幂次的和1,2,4……, 多余出来的也放进去,再将这些数乘以原价值,原重量,单作不同的物品加进去。为什么要这么做呢?假设我们当我们取k件该物品时,k同样可以看成分解出来的数的组合。然后就是普通背包的思路了。#include<stdio.h原创 2020-12-09 11:22:00 · 728 阅读 · 0 评论 -
Dijisktra 算法————邻接表实现、邻接矩阵实现、以及堆优化
Dijisktra算法用于求单源最短路径,对图的要求有:(1)无负环(否则求出的结果为负无穷)算法思路:将顶点集分成两部分S、V-S,S为已经找到到源点最短路的顶点集合。1.将源点插入S,到自身距离为0;2.遍历刚插入节点的所有边,更新V-S中顶点到源点的距离;3.在V-S中找到距源点最短的结点,插入S,回到第2步。若未找到1.结点遍历完2.若距离都为设置的极大值,则这些源点没到这些结点没有路径。C语言实现(有向图)1. 邻接表实现#include<stdio.h>#inc原创 2020-11-27 11:03:11 · 1402 阅读 · 0 评论 -
P2196 挖地雷————动态规划(洛谷)
P2196#include<stdio.h>#include<stdlib.h>#define MaxSize 25int way[MaxSize][MaxSize],dp[MaxSize][MaxSize],root[MaxSize][MaxSize];void print(int a,int b);void find(int n ,int *all){ int i,j,k,l,tmp,tmpi,tmpj; for(i=1;i<=n;i++){ dp[i]原创 2020-11-16 19:58:18 · 298 阅读 · 0 评论 -
P1049 装箱问题
P1049 装箱问题背包问题。模板题。标记每个可能的重量。#include<stdio.h>#include<stdlib.h>#define size 100int v[size], w[size], sum[30005];void find(int n, int m) { int i, j, k; sum[0] = 1; for (i = 0; i < m; i++) { for (j = n; j >= v[i]; j--) { if (原创 2020-11-16 19:47:44 · 93 阅读 · 0 评论 -
P1833 樱花(洛谷)——————动态规划
P1833 樱花多重背包问题,(每一个物品数目有限)数据量较大,因此使用二进制优化即可过。#include<stdio.h>#include<stdlib.h>int v[200000],w[200000],c[1005];void find(int n,int t){ int i,j,k; for(i=0;i<n;i++){ for(j=t;j>=w[i];j--){ c[j]=c[j]>c[j-w[i]]+v[i]?c[j]:c[j-w[原创 2020-11-16 19:43:45 · 192 阅读 · 0 评论 -
P1564 膜拜(洛谷)——————动态规划
P1564 膜拜这一题使用递归求解,考虑一个区间[i,j],若从i到j可分在一个机房,则直接返回,否则,遍历每一个点k,若[i,k]可分在一个机房,则求[k+1,j]分组的数目最小值。求解过程中,已求的区间会被存储起来。(这里固定n)#include<stdio.h>#include<stdlib.h>#include<math.h>#define size 2505#define max 9999int a[size], b[size], cnt[siz原创 2020-11-16 19:38:58 · 136 阅读 · 0 评论 -
P1077 摆花(洛谷)——————动态规划
P1077 摆花模板题。对于没一盆花遍历从n到1的每一个花的总数,再对摆放该花的盆数k进行遍历。状态转移方程为cnt[j]+=cnt[j-k]#include<stdio.h>#include<stdlib.h>#define size 150int a[size], cnt[size];void find(int n, int m) { int i, j, k; cnt[0] = 1; for (i = 0; i < n; i++) { for (j原创 2020-11-16 19:29:07 · 105 阅读 · 0 评论 -
P1507 NASA的食物计划(洛谷)————动态规划
P1507 二重背包问题,模板题;三重循环分别遍历每一件物品,每一个体积,每一个重量#include<stdio.h>#include<stdlib.h>#define size 405int carol[size][size],w[size],v[size],ca[size];void find(int va,int mm,int n){ int i,j,k,tmp; for(i=0;i<n;i++){ for(j=va;j>=v[i];j--){原创 2020-11-15 21:50:39 · 210 阅读 · 1 评论 -
P1359 租用游艇————动态规划
P1359思路:从1到n的最短路径?有向图?不妨考虑先从1到i,再考虑从i到n的最短路径。因此自底向上,从n-1到n的最短路径开始计算。ac代码:#include<stdio.h>#include<stdlib.h>#define size 205 #define max 9999999int r[size][size];void find(int n){ int i,j,k; for(i=n-1;i>=1;i--){ for(j=i+1;j<=n原创 2020-11-14 10:54:58 · 178 阅读 · 0 评论 -
钢条切割————算法导论
给定长度任意长度的钢条的价值,求解如何切割,使给定长度为n的钢条的价值最大。对于长度为n的钢条,考虑子问题,我们遍历1~n的第一个切割的位置j,即得到长度为j和n-j的两段钢条,第一段不再切割,仅对第二段继续切割,递归求解,于是就得到了一个递归解法。这里是C语言实现#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#define min -999999#define maxsize 9999原创 2020-11-14 10:20:25 · 239 阅读 · 0 评论 -
P1044 栈(洛谷)————动态规划
P1044 #include<stdio.h>#include<stdlib.h>#define Max_N 30int dp[Max_N][Max_N];//i待排元素数目,j栈中元素 ,输出序列可能 int Recursion_Find(int i,int j){//递归查找 if(dp[i][j])return dp[i][j];//若dp[i][j]已存在则直接输出 if(j>0) dp[i][j]+=Recursion_Find(i-1,j+1)+原创 2020-10-30 21:38:34 · 379 阅读 · 0 评论 -
矩阵链乘法(最优解)————算法导论(C语言实现)
这两天算法课刚学了这个,于是就想着用C语言自己撸出来首先是寻找最优解的过程,对于下标从i到j的矩阵链,我们将其分成两部分i到k和k+1到j,遍历每一个k,找到最小值即可。因此我们需要从下往上遍历矩阵链长度。这里是c代码#include<stdio.h>#include<stdlib.h>#define maxSize 1000#define maxNum 100000000int dp[maxSize][maxSize];//从i到j相乘所需要的最少计算次数 in原创 2020-10-29 11:19:48 · 2175 阅读 · 0 评论