算法
倩音流年123
这个作者很懒,什么都没留下…
展开
-
求最长上升子序列的长度和输出相应序列dp总结
代码:#include<bits/stdc++.h>using namespace std;int a[100],s[100],dis,cot,n,maxz; //s数组用来存放最长上升子序列的内容;int dp[100]; //dp[i]表示以i位置结尾的最长上升子序列的长度 ;int main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i];for(int i=1;i<=n;i++){dp[i]=1;原创 2020-10-24 18:13:34 · 369 阅读 · 0 评论 -
蓝桥杯算法提高VIP1923 学霸的迷宫
输入:第一行两个整数n, m,为迷宫的长宽。接下来n行,每行m个数,数之间没有间隔,为0或1中的一个。0表示这个格子可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫的出口在(n,m)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)可以通过。输出:第一行一个数为需要的最少步数K。第二行K个字符,每个字符∈{U,D,L,R},分别表示上下左右。如果有多条长度相同的最短路径,选择在此表示方法下字典序最小的一个原创 2020-10-05 21:00:11 · 237 阅读 · 0 评论 -
求字典序最小的字符串总结
最小字典序:题目描述:给定长度为N的字符串为S,要构造一个长度为N的字符串T。起初,T 是一个空串,随后反复进行下列任意操作。①:从S的头部删除一个字符串,加到T的尾部,②:从S的尾部删除一个字符,加到T的尾部思路解析:将字符串S和反转后的字符串S‘逐一进行字符的比较,若前者第一个小于后者第一个,则将S的首字符放入T中,若S的首字符大于S’的首字符,则将S‘的首字符放入到T中,若两者相等,则都可以;代码://求字典序最小的字符串#include<bits/stdc++.h>us原创 2020-10-05 17:03:58 · 3019 阅读 · 0 评论 -
洛谷P1657选书总结
总结:本题依然是典型的DFS题目,状态空间很好想,就是x即第几个人,关键是每个人喜欢两本书如何存储此状态,有点懵,看了下题解,比较好的办法就是设置like[i][j]数组,表示第i个人喜欢第j本书,一个简单的二维数组巧妙地解决了这个问题,接下来就是递归搜索:注意有易错点:1.当ans=x时放在for循环语句里,计数加1,此时不要return,并不是每个递归终止都要写return语句,写了后本题会报错,因此需要就题论题,思维不能僵化;2.回溯语句都要放在else外面,之前刷题时也注意到,这里在强化记忆原创 2020-09-23 19:57:19 · 177 阅读 · 0 评论 -
洛谷1036选数总结
思路总结:本题还是典型的DFS题目,关键在于状态空间的选取,我想了想,用void DFS(int now,int sum),其中now表示从n个数中选取k个数,相当于放在k个位置,now即代表第几个位置,sum表示求和,但是在for循环选数的时候,思路卡了壳,原因就是每次都是从1~n选取,会有数的重复,时间复杂度也不划算,看了下题解,发现别人用的是void DFS(int x,int y)表示,其中x表示已经选了几个数,当xk时,表示k个数已经全部选取完毕了,y表示从第几个数开始选取,for循环:for(原创 2020-09-17 20:13:09 · 283 阅读 · 0 评论 -
极值OJ抓住那头牛总结
总结:本题是非常经典的BFS搜索类型,由于农夫每走一步都有三种选择或三种决策,走到当前状态时又是从上一个状态转移过来,类似于树一层一层地去搜索遍历,每个子节点有三个“儿子”,从而遍历整棵树,找到时间的最小值,总结以后遇到枚举当前状态空间时,若出现多种选择或决策时,应该优先考虑广搜BFS!!!错因:本题思考了将近20分钟,没有思路,关键在于对于广搜BFS的应用场景不是很熟悉,一开始的出发点都错了,因为本题在枚举每一步的状态空间时,都会遇到三种选择,明显用BFS做更合适。代码:#include<b原创 2020-08-26 18:49:12 · 102 阅读 · 0 评论 -
洛谷P1451求细胞数量再总结错因
总结:本体考虑用DFS解决问题时,发现了两个之前并没在意的错因,第一个便是在编写搜索函数时,对于搜索的条件并没有设置,导致没有编译通过,程序报错,以本题为例,递归终止条件自然不用多说,即是否越界,而搜索之前,须先判断当前位置是否为细胞数字,是的话,才去搜索,否则不搜;前几次编译的时候,就因为没有设置该条件,导致程序无法运行,直接终止了。第二个便是一直忽略的错误,比如去枚举搜索四个方向时,注意观察一下两个程序的区别,此处细节直接决定成败!方向1:(程序错误展示)int dx[4]={-1,1,0,0};原创 2020-08-26 17:15:11 · 183 阅读 · 0 评论 -
图的存储—邻接表代码总结
#include<bits/stdc++.h>#define maxn 111111using namespace std;struct edge{int to,val;};vector p[maxn];int v[maxn][maxn];int main(){int n,m; //n个顶点,m条边;for(int i=1;i<=m;i++){int u,v,l;cin>>u>>v>>l;p[u].push_back((ed原创 2020-08-14 09:53:10 · 237 阅读 · 0 评论 -
洛谷P2802回家(DFS,剪枝)
题目总结:本题需要注意两点:1.属于求最小值的DFS问题,没有明显的结束递归标志,一般这种情况设置上界,当超出上界时,退出;比如nm格子组成的网格图,从起点出发枚举搜索,当步数>mn时,退出递归,作为结束标志;2.本题常规搜索DFS,会超时,需要进行适当的剪枝操作,比如本题求最小值,当目前状态搜索的值大于之前已求出的最小值,则return 退出;同理,如若要求最大值,若此时的状态值小于之前求出的值,则return掉,节省时间复杂度; 代码: #include<bits/stdc++.h原创 2020-08-03 22:12:11 · 238 阅读 · 0 评论 -
洛谷1030求先序排列(DFS)
题目内容:给出一棵树的中序和后序排列,输出先序排列;样例:中序:BADC后序:BDCA输出:ABCD思路:根据树的遍历知识,后序的最后一个节点都代表一棵子树的根,如本例A为主根,然后从中序中遍历寻找主根A的位置,从而划分出左右子树;根据左右子树结点的个数,将后序划分,继续按之前操作步骤,递归搜索,先输出跟,再找左右子树,直到空树为止。代码:#include<bits/stdc++.h>using namespace std;string s1,s2;void dfs(int原创 2020-08-03 15:08:41 · 196 阅读 · 0 评论 -
洛谷1451求细胞数量题解 (DFS,BFS)
题目内容:有一个nxm矩阵,存放细胞,其中细胞数字为1~9,非细胞数字为0,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。(注意:除了n,m外,其他n行m个数输入均为字符,需要转换)思路一:DFS深搜:逐个去枚举(1,1)–(n,m),判断哪些是细胞数字,哪些已经被访问过,未被访问过且是细胞数字的坐标标记为true,count1++,同时再去寻找它的上下左右四个方向,标记与它相邻的细胞,统一计数为相同细胞;代码:#include<bits/stdc++.原创 2020-08-02 16:37:41 · 543 阅读 · 0 评论 -
洛谷1507NASA的食物计划
思路:典型的0-1背包问题,不过是在传统的基础上变成了两个限制条件:体积V和质量M;有两种方法,一种是开三维的f[i][j][k],写个三层for循环,来找f[N][V][M]的最优值;另一种是开二维的f[j][k],前者表示体积,后者表示质量,然后遍历.代码一:三维#include<bits/stdc++.h>using namespace std;int V,M,N,v[50],m[50],c[50];int f[50][401][401],j,k;int f2[401][4原创 2020-07-25 11:17:23 · 79 阅读 · 0 评论 -
Leetcode二叉树最大深度(DFS,BFS)
给定一个二叉树,找出其最大深度。二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。说明: 叶子节点是指没有子节点的节点。代码:#include<bits/stdc++.h>#includeusing namespace std;struct TreeNode{ int val; TreeNode *left; TreeNode *right; TreeNode(int x): val(x),left(NULL),rig原创 2020-07-24 09:36:29 · 157 阅读 · 0 评论 -
二叉树之先序,中序,后序遍历的两种方法:递归和非递归+层序遍历的BFS
//总结二叉树中的先序,中序,后序,层序://一.递归:#include<bits/stdc++.h>#include#include#includeusing namespace std;struct TreeNode{int val;TreeNode *left;TreeNode *right;TreeNode(int x):val(x),left(NULL),right(NULL) {}};//先序递归:void preOrderRecur(TreeNode原创 2020-07-23 11:51:52 · 100 阅读 · 0 评论 -
洛谷2074危险区域总结
思路总结:推荐使用深搜DFS,本题陷入一个误区,误以为有k个炸弹区域,实际题目应理解为在NM个街道内,只有一个炸弹放置点,但是该位置不确定,有k个怀疑的地方,所以应枚举这k个区域,要做最坏情况,即找在k种情况下,哪种地区街道受威胁的个数最多;其次,本题放在NM矩形区域内,以N代表横轴,M代表纵轴,不好理解的话,可以这样思考,将N*M区域逆时针旋转90度,N落在x轴上,M落在y轴上,枚举直线距离小于等于该爆炸点的街区,并最终在k种情况下,取最大值,即为最坏情况;代码:#include<bits/原创 2020-07-21 17:50:18 · 132 阅读 · 0 评论 -
图论之dijkstra算法求最短路:
//dijkstra算法求最短路:#include<bits/stdc++.h>using namespace std;#define N 3000const int INF=0x3f3f3f3f;int dis[N],vis[N],edge[N][N],pre[N];int a,b,w,s,t,n,m; //w为权重,s,t分别为指定的求最短路的起点和终点;int main(){ void search(int x); void dijkstra();原创 2020-07-14 15:59:45 · 221 阅读 · 0 评论 -
图论之Floyd算法总结
一.求任意两点间的最短路径(有权图)Floyd算法代码:#include<bits/stdc++.h>using namespace std;int dis[100][100],x,y,z;int n,m,p; //n,m分别代表图的边和节点int main(){ memset(dis,0x3f,sizeof(dis)); cin>>n>>m; for(int i=1;i<=n;i++) {原创 2020-07-13 22:26:54 · 318 阅读 · 0 评论 -
数据结构之链表操作总结
1.以双向链表为例,插入操作代码:先以结构体存储节点的键值,前驱和后继struct node{int x;node *next,*pre;node(int _x,node *_pre,node *_next) : x(_x),pre(_pre),next(_next) { }};node *head=new node(0,NULL,NULL); //先插入节点 void insert(node *p,int x) { node *q=new node(x,p,p->nex原创 2020-07-12 22:18:23 · 120 阅读 · 0 评论 -
分组背包优化总结
优化思想:采用二进制优化,即在原先从1开始枚举到n的过程中,将n拆分成1,2,4,8,16,32…即2的整数次幂,剩余的没法组成2的整数次幂的单独分成一组,比如123=1+2+4+8+16+32+60,由于64>60,所以60单独分成一组,则在[1,63]区间内任意整数都可由2的整数次幂来表示,比如35=32+2+1,37=32+4+1;而[64,123]区间内的任意整数可由[1,63]加上60即可表示,从而将枚举的时间复杂度n变成log2n,利用新分成的组数进行0-1背包代码:int kind原创 2020-07-10 22:34:21 · 565 阅读 · 1 评论 -
区间DP总结
一.序列是一个链(非环),求从区间(l,r)之间的最大得分,典型问题:石子数问题。f(l,r)表示把第l堆到第r堆的石子合并在一起的最大得分,最后合并在一堆的石子来源于前两堆,其中一堆在(l,k),另一堆在(k+1,r)区间内,而k范围在l~r-1内,所以只需枚举k即可求出。动态转移方程: f(l,r)=max(f(l,k)+f(k+1,r)+sum(l,r))其中sum(l,r)用前缀和求出:sum(l,r)=r-l+1;二.如果要寻找的最大得分是一个圈(即环):假设一个圈个数为n,将他们扩展成原创 2020-07-06 10:31:23 · 112 阅读 · 0 评论 -
总结0-1背包和完全背包代码:
一.不考虑时间复杂度和空间复杂度,只考虑正确性的传统模板:(1) 0-1背包:n表示物品个数,c[i]表示第i个物品的价值,v[i]表示第i个物品的容积,给定背包总容积Vfor(int i=1;i<=n;i++){for(int j=0;j<=V;j++){f[i][j]=f[i-1][j];if(j-v[i]>=0)f[i][j]=max(f[i][j],f[i-1][j-v[i]]+c[i]);}}int ans=0;for(int i=0;i<=V;i+原创 2020-07-02 22:51:06 · 378 阅读 · 0 评论 -
洛谷1734“最大约数和”问题(典型动规背包)
题目描述选取和不超过S的若干个不同的正整数,使得所有数的约数(不含它本身)之和最大。输入格式 输入一个正整数S。输出格式 输出最大的约数之和。思路:本题属于典型的动态规划0-1背包问题,即若干个不同的正整数,每个数最多取一次,修改下0-1背包模板即可,主要是多了求正整数的约数和步骤。先找对应指标,S即为背包容积V,i从1~S即为个数,a[i]存储每个数的约数和代表价值,例如a[6]的约数和1+2+3=6(不包括本身),使约数和最大。第一步:先用函数求每个数的约数和:int find(int x)原创 2020-07-02 21:34:54 · 599 阅读 · 0 评论 -
2013蓝桥杯真题: 危险系数
问题描述抗日战争时期,冀中平原的地道战曾发挥重要作用。地道的多个站点间有通道连接,形成了庞大的网络。但也有隐患,当敌人发现了某个站点后,其它站点间可能因此会失去联系。我们来定义一危险系数DF(x,y):对于两个站点x和y (x != y), 如果能找到一个站点z,当z被敌人破坏后,x和y不连通,那么我们称z为关于x,y的关键点。相应的,对于任意一对站点x和y,危险系数DF(x,y)就表示为这两点之间的关键点个数。本题的任务是:已知网络结构,求两站点之间的危险系数。输入数据第一行包含2个整数n(2原创 2020-06-30 17:27:08 · 126 阅读 · 0 评论