随笔分类 -  算法学习

算法竞赛
摘要:最小生成树的概念 给定无向图G = (V, E),连接G中所有点,且边集是E的子集的树称为G的生成树,而权值和最小的生成树称为最小生成树,即MST。 构造MST的方法有很多种。常用的有Kruskal算法和Prim算法,前者好写,时间复杂度为O(m),后者稍微难写,时间复杂度O(n*n)。(n为树的节点数,m为边数)。 Kruskal算法(摘自刘汝佳白书P199): 算法的第一步是给所有边按照从小到大的顺序排序,然后从小到大考查所有边。考查到边(u, v)的时候有两种情况: 情况1:u, v此时属于同一个连通分量中,则加入(u, v)会形成环,不能加入该边。 情况2:u... 阅读全文
posted @ 2013-12-12 20:18 Plumrain 阅读(771) 评论(0) 推荐(0)
摘要:在图论中,求MST的Prim算法和求最短路的Dijskra算法非常像。可是我一直都对这两个算法处于要懂不懂的状态,现在,就来总结一下这两个算法。最小生成树(MST)—Prim算法:算法步骤:•将顶点集V分成两个集合A和B,其中集合A表示目前已经在MST中的顶点,而集合B则表示目前不在MST中的顶点。•寻找与集合A连通的最短的边(u,v),将这条边加入最小生成树中。(此时,与(u,v)相连的顶点,不妨设为Bi,也应加入集合A中。•重复第二步,直至集合B为空集。正确性证明:1、由归纳法可知,只需要证明 “每次向集合A中加入一条边后都能保证,集合A这个生成树是关联到集合A中所有点的最小生成树”,就能 阅读全文
posted @ 2013-11-30 23:17 Plumrain 阅读(3358) 评论(0) 推荐(0)
摘要:并查集是一个高效的数据结构,最简单的作用是用来判断图中的两个点是不是属于同一个连通分量。我们可以将图中的每一个连通分量看成一个集合,每个集合都有一个特征值。比如{1,2,3,4}的特征值为1,那么记f[1] = f[2] = f[3] = f[4] = 1,则这样可以通过判定两个点的f值来判定是不是属于同一个连通分量。然后,我们用树的形式来记录集合,并且这个树只需要包含集合中的所有点即可,而不需要在意树的具体形式。而这个集合的特征值,则为根节点的节点编号。这样的话,如果该树是条长长的链,则每次求叶子节点的f值时都需要几乎遍历所有节点,这样的话时间复杂度就会很高。所以,我们每次求了一个点的f值都 阅读全文
posted @ 2013-11-30 01:20 Plumrain 阅读(332) 评论(0) 推荐(0)
摘要:对于”把一个向量v变成另一个向量v',并且v'的每一个分量都是v的各个分量的线性组合”这样的问题,一般都可以考虑用矩阵乘法来描述他们的变化关系。而用矩阵乘法的好处在于,可以使用快速幂来优化时间复杂度,将原本O(n)的递推优化到O(logn)。 解决这类问题,最简单也最常见的例子莫过于求Fibonacci数列中的第n项,比如POJ 3070Fibonacci。并且,题目已经构造好了转化矩阵,见下图。 . 注意,这样的方法只能求出最标准的Fibonacci数列的第n项,即1,1,2,3,5...如果F(0)和F(1)改变,还需要对这个等式稍做变动。这样的题,比... 阅读全文
posted @ 2013-10-29 15:21 Plumrain 阅读(895) 评论(0) 推荐(0)
摘要:最近看了潘震皓的《置换群快速幂运算 研究与探讨》,总结一下。具体推导过程参见原文。1、置换群的乘方:求T^k(k为正整数)对于置换T,用数组a[i][]表示置换T的循环,约定a[i][0]为该循环内最小的数,且l[i]表示对应循环的长度,记。:对每个循环,若l[i]是k的倍数,则乘方之后分裂为k个循环,并且每个循环分别是循环a[i]中下标j mod k = 0, 1, 2....的元素按顺序连接。对每个循环,若gcd(l[i], k) = 1,则乘方之后仍然是一个循环,设原循环为数组a[i],长度为l[i],乘方之后为a[i]',则a[i]'[j] = a[i][k*j mod 阅读全文
posted @ 2013-10-23 15:00 Plumrain 阅读(1621) 评论(1) 推荐(0)
摘要:大素数检测大素数检测常用的方法为miller_rabin。网上讲这个方法的文章博客已经很多了,我在这里就只转载一篇别人的文章。原文出处:http://www.cppblog.com/zoyi-zhang/archive/2008/09/23/62572.aspx 1 大素数的检验 2 费马小定理:a^(p-1) mod p = 1(p是素数&&a0) 3 4 首先我们证明这样一个结论:如果p是一个素数的话,那么对任意一个小于p的正整数a,a, 2a, 3a, …, (p-1)a 5 除以p的余数正好是一个1到p-1的 6 排列。例如,5是素数,3, 6, 9, 12除以5的余数分别为3, .. 阅读全文
posted @ 2013-10-23 12:48 Plumrain 阅读(2496) 评论(0) 推荐(0)
摘要:问题:给定一个正整数m和两个正数数组a[n]和b[n]。对于数组x[n],x[n]中有m个i使得x[i] = 0,其余x[i] = 1,并且令R = segma(a[i]*x[i]) / segma(b[i]*x[i])。求一个满足条件的x[n],使得R的值最大,输出R的最大值。分析:构造函数F(L) = segma(a[i]*x[i]) - L * segma(b[i]*x[i]) = segma((a[i] - L * b[i]) * x[i])。令c[i] = a[i] - L * b[i]。 观察F(L),发现以下性质:1、若L固定,则可以通过一次对c[i]的排序,找到使得F(L).. 阅读全文
posted @ 2013-10-12 18:49 Plumrain 阅读(394) 评论(0) 推荐(0)
摘要:可能是目前做的这类题都比较简单,所以几乎都是套上模板就差不多了.....这里copy一份czyuan大神的模板 1 /* 用于求整数解得方程组. */ 2 #include 3 #include 4 #include 5 using namespace std; 6 const int maxn = 105; 7 int equ, var; // 有equ个方程,var个变元。增广阵行数为equ, 分别为0到equ - 1,列数为var + 1,分别为0到var. 8 int a[maxn][maxn]; 9 int x[maxn]; // 解集. 10 bool fr... 阅读全文
posted @ 2013-10-08 20:16 Plumrain 阅读(493) 评论(0) 推荐(0)
摘要:Ps:很久以前学的,一直以来都是套模板,感觉忘得差不多了,所以复习一下- -欧几里得算法作用:计算两个数的最大公约数。算法:欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。用gcd(a, b)表示a和b的最大公约数。gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(-a,b)=gcd(|a|,|b|)=gcd(a,b-a)C实现:1 typedef long long int64;2 3 int64 gcd(int64 a, int64 b)4 {5 return b == 0 ? a : gcd(b, a% b);6 }View Code 扩展欧几里得... 阅读全文
posted @ 2013-09-04 20:22 Plumrain 阅读(292) 评论(0) 推荐(0)
该文被密码保护。
posted @ 2013-08-24 16:47 Plumrain 阅读(6) 评论(0) 推荐(0)
摘要:今天看刘汝佳的白书《算法竞赛入门经典 训练指南》中写到,所以在网上学习了一下。简介 卡特兰数(Catalan),又称卡塔兰数,事组合数学中常出现在各种计数问题中的一个数列。以比利时数学家欧仁 查理 卡塔兰命名。其前几项为1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190....性质递推公式1:an = a0 * an-1 + a1 * an-2 + …....... + a(n-1. 阅读全文
posted @ 2013-08-14 00:35 Plumrain 阅读(872) 评论(0) 推荐(0)