zoukankan      html  css  js  c++  java
  • 简单算法复习

    个人认为,信息学竞赛中最难的部分,要数算法的学习和灵活运用了吧。其实算法呢,讲讲概念很好理解,可一道题目中,就千变万化,纯看个人造诣了。本人在这方面比较弱。。。讲的太浅显,或者有什么问题还请不吝赐教。

    1.搜索

    好的搜索是一门艺术,是优雅的暴力。

    这几天的的模拟赛告诉我一个真理:练好搜索!练好搜索!!练好搜索!!!毕竟我们实力有限是吧。所以说正解不强求,但暴力分怎么也得拿一点啊。

    无奈基础太差,优化算法涉猎较少,现在摆出这几天刷的题吧。

    求先序排列:大水题(PJ),但是让我对树的先序,中序,后续排列有了一些理解

    高手去散步:DFS水题

    家族:BFS水题,但是其中对字符串的处理值得学习

    NOIP2003传染病控制:树上搜索,自习想想还是比较好理解的

    *NOIP2016愤怒的小鸟:搜索策略不再是单纯的枚举,细节方面也有很多注意的地方。

    *NOIP2004虫食算:有技巧的搜索

    *NOIP2015斗地主:较复杂的搜索,代码量大。

    其他OJ上的题,看了一些但是没写了。只能说自己刷题量还是太少了吧。

    需要学习的部分:DFS剪枝,迭代加深,双向广搜,启发式搜索。

    2.分治

    这几天学的东西,大部分的与分治有关。

    分治,字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。上面详细讲的树状数组和线段树,其实都是分治思想的体现

    也不多讲,以题目为例吧:

    平面内最近点对:好题嗯。大局分治,局部暴力。

    最小三角形:和平面内最近点对差不多,是落实的好题。

    *BZOJ4985: 评分:二分+DP?思想极其巧妙。

    *BZOJ4592:脑洞治疗仪:线段树/珂朵莉树高级题目。

    以上分治题目的质量还是非常高的,值得好好咀嚼吸收。

    *3.动态规划

    已放弃治疗。。。

    如果没退役我一定恶补DP!!! QAQ

    4.图论

    划重点好啦其实就是板子比较多。

    1.最短路

     Dijkstra算法(堆优化):

    priority_queue < pair <int,int> > q;    //优先队列(大根堆)修改为小根堆
    int dis[N];          			//dis数组:dis[i]表示i点到起点s的距离,初始化为无穷大
    bool v[N];							//v数组:节点是否被松弛过
    void Dijkstra(int s)
    {
        for(int i=1;i<=n;i++)
    	dis[i]=2147483647;
        dis[s]=0;
        q.push(make_pair(dis[s],s));     //初始节点入队
        while(q.size())
        {
    	int x=q.top().second;q.pop();         //出队
    	if(!v[x])            //如果没被松弛过
    	{
    	    v[x]=1;						//记为已松弛
    	    for(int i=head[x];i;i=e[i].nxt)     //遍历所有邻边
    	    {	
    		int y=e[i].to;					
    		if(dis[x]+e[i].v<dis[y])				//如果能松弛
    		{
    		    dis[y]=dis[x]+e[i].v;    			//更新
    		    q.push(make_pair(-dis[y],y));    //入队
    		}
    	    }
    	}
        }
    }
    

    至于SPFA...求负环还不是很熟。不写了。

    *地铁涨价:最短路+动态加边

    *2.二分图匹配

    学了但不熟。不写。

    3.最小生成树

    算法实现挺容易的吧。(Kruskal)就是并查集+贪心。

    不过关键的一点就是看你能不能将题目转换成最小生成树的题目。就比如上次选拔考试 水滴 那个题,表面上是暴力模拟,实际上可以建图+最小生成树来做。

    还有一个题目:洛谷P1550:一点思维就能转化为最小生成树的水题。

    4.强连通分量

    Tarjan不熟。。。先把板子背了吧。

    DFN[ i ] : 在DFS中该节点被搜索的次序(时间戳)

    LOW[ i ] : 为i或i的子树能够追溯到的最早的栈中节点的次序号

    void tarjan(int i)
    {
    	int j;
    	dfn[i]=low[i]=++time;
    	in[i]=1;sta[++top]=i;
    	for (int e=head[i];e;e=edge[e].next)
    	{
    		j=edge[e].to;
    		if(!dfn[j])
    		{
    			tarjan(j);
    			if (low[j]<low[i])low[i]=low[j];
    		}
    		else if (in[j] && dfn[j]<low[i])
    			low[i]=dfn[j];       //注意细节
    	}
    	if (dfn[i]==low[i])    //判断条件
    	{
    		Bcnt++;
    		do
    		{
    			j=sta[top--];
    			in[j]=0;
    			belong[j]=Bcnt;
    		}while(j!=i);
    	}
    }
    

    Desperados no way back.
  • 相关阅读:
    适配器
    MouseListener
    键盘事件KeyListener
    【转】CxImage图像库的使用
    【转】Qt Mode/View
    【转载】VC++中的图像类型转换--使用开源CxImage类库
    Qt5 文本编辑
    【转载】设备坐标(窗口/window)和逻辑坐标(视口/viewport)
    【转载】Qt中的QString,QByteArray,Qchar, char*
    QT中QWidget、QDialog及QMainWindow的区别
  • 原文地址:https://www.cnblogs.com/Zerosking/p/10011086.html
Copyright © 2011-2022 走看看