算法
vufw_795
Mood decides everything.
展开
-
素数筛法
平常的素数求法太慢了,所以需要加一下速。第一种,筛法的最基本做法,但是效率不是很高:bool prime[MAXN+5];int ans[MAXN+5],cnt;void getPrimeSlower(int n){ memset(prime,1,sizeof(prime)); cnt=0, prime[0]=prime[1]=0; for(int i=2;i<=n;i+原创 2015-10-31 12:07:37 · 609 阅读 · 0 评论 -
URAL 1326(状态压缩DP)
题目链接:URAL 1326解题思路: 状态压缩DP,也就是集合的DP,思路跟TSP问题很相似。需要注意的就是可以买多T^T代码:#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define INF 0x3f3f3f3fusing namespace std;const int MAXN原创 2016-02-03 23:41:25 · 673 阅读 · 0 评论 -
POJ 2195(二分图最大权匹配)
题目链接:POJ 2195解题思路: 这题可以转化成权匹配或者费用流问题。首先需要根据输入构图,将问题转成权匹配问题,之后套用KM算法即可。KM算法入门很好的一道题目。代码:#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define INF 0x3f3f原创 2016-02-21 21:13:31 · 949 阅读 · 0 评论 -
UVA 11021(概率DP)
题目链接:UVA 11021解题思路:这题算是一道很经典的概率入门题了吧,不过首先得知道可以用pow函数。虽然题目中讲的是K个毛球,但是其实可以考虑一个毛球的情况,之后作K次方即为答案。原创 2016-03-07 15:57:21 · 565 阅读 · 0 评论 -
CodeForces 302C(数学)
操作要求是选n个数,改变它们的符号,使得所有数的和最大。n为奇数时,翻转几个数都是可行的;n为偶数时,只能翻转偶数个数,所以我们要留一个绝对值最小的数为负数。原创 2015-10-01 00:13:47 · 421 阅读 · 0 评论 -
动态规划学习系列——划分DP(二)
划分型DP第二题,wikioi 1039,与第一题乘积最大思路有所不同。题目要求: 将一个数划分成几部分,问一共有多少种分法。 真 · 解题思路: 其实跟小学奥赛的一些题有点像,我们先来看一个例子: 7 分成 3 部分,有四种办法: 1,1,5;1,2,4;1,3,3;2,2,3 。 我们人脑来考虑问题的时候是怎么想的呢?显然,从1开始,1是第1部分,然后剩下6分成2部分,我们依然是从1原创 2015-02-21 16:08:34 · 1642 阅读 · 0 评论 -
POJ 2096(概率DP)
题目链接:POJ 2096解题思路: 总的来说状态方程还是蛮好想的,每次找bug的时候,有可能会出现四种情况,一是在已经找到bug的系统中找到了旧bug,二是在新的系统中找到旧bug,三是在已经找到bug的系统中找到了新bug,二是在新的系统中找到新bug。于是,状态dp[i][j]表示在 j 个系统中找到 i 个bug需要的天数期望,初始状态dp[0][0]=0,状态转移方程如下:dp[i][j原创 2016-02-24 16:48:31 · 566 阅读 · 0 评论 -
UVA 10537(最短路)
题目链接:UVA 10537解题思路: 这题是大白书上的最短路例题,应用情景非常经典。首先我们在计算最短路的时候需要从终点算起,因为图中边的权值是变化的;计算的方法是一个坑,大概就是对于一个整数N,求一个整数M,使得N=M−⌈M/20⌉N=M-\lceil M/20\rceil式子是这样的M=⌈19N/20⌉M=\lceil 19N / 20 \rceil,公式的得出需要先考虑M可以被20整除的情原创 2016-04-03 21:47:27 · 1289 阅读 · 0 评论 -
UVA 11090(SPFA判负环)
题目链接:UVA 11090解题思路: 这题需要使用二分法来解决,思路类似与最大值最小化问题,我们可以把求解最小均值环的问题转化成判断负环的问题。二分的过程中,我们可以每次猜想一个最小值,然后使所有的边的权值减去这个最小值,若存在负环,则这个值太大了,最小值需要减小,否则增加。判断负环可以使用Bellman-Ford算法的优化算法,SPFA算法解决。代码设计: 因为最小均值可以为浮点数,而且只需原创 2016-04-04 14:02:40 · 900 阅读 · 0 评论 -
匹配及其相关问题(二)
前言: 很久之前学的一个算法,然而昨天发现我已经完全不记得原理了。上周末去打补选赛,看到一堆时间复杂度没救的图论题,心灵受到了成吨的伤害。老师说算法设计要考网络流,如果不学学二分图匹配的话估计又要GG了。简介: 匈牙利算法,由匈牙利数学家Edmonds与1965年提出,属于比较早期的一个算法。算法的核心在于寻找增广路径,是一种用增广路径求解二分图最大匹配的算法。情景说明: 我们首先给出问题的具原创 2015-12-31 21:22:02 · 965 阅读 · 0 评论 -
UVALIVE 2678
题目链接:UVALIVE 2678解题思路: 这题一共有两种做法,一种是二分法,时间复杂度为O( n*log(n) );一种是直接遍历,时间复杂度为O( n )。 二分: 维护一个sum数组,保存数列前 i 项和,之后对每一个大于m的sum[i],使用二分查找找到sum[i]-m的lowerbound。 遍历: 同样维护sum数组,并且维护两个指针,表示满足条件的区间,之后在遍历数组的过程原创 2016-03-03 10:13:53 · 641 阅读 · 0 评论 -
POJ 1094(拓扑排序)
题目链接:POJ 1094解题思路: 基本的思路就是拓扑排序算法。需要注意的是环的判断优先于排序是否唯一的判断。代码:#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int n,m,a[30][30],degree[30原创 2016-02-14 00:59:46 · 665 阅读 · 0 评论 -
威佐夫博弈(介绍)
题目大意: 有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子,游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者,现在给出初始的两堆石子的数目,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。 这就是著名的威佐夫博弈,这里列出几种先手必败的局势,(1,2),(3,5),(4,7),原创 2015-11-01 20:00:03 · 606 阅读 · 0 评论 -
动态规划学习系列——数位DP(练手四)
题目链接:hihoCoder 1033解题思路: 思路超级简单,就是单纯的数位DP,但是,还是觉得好恶心。需要特殊考虑的就是第一位数字为0的情况,不能直接把状态转移的结果拿出来。 状态:dp[i][j][k+100],i 位数中以 j 开头的数交叉和为k的数量原创 2015-11-28 09:30:21 · 482 阅读 · 0 评论 -
统计回文子序列(动态规划)
dp[i][j]代表区间[ i , j ]中回文子序列的个数……#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MOD 100007using namespace std;char st[1005];int a[1005],dp[1005][1005];int main()原创 2015-12-31 16:46:41 · 1146 阅读 · 0 评论 -
HDU_1576(乘法逆元)
题目链接:HDU_1576题目说明: 乘法逆元的应用,测一发模板(用模线性方程做的)代码:#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;long long extend_gcd(long long a,long lo原创 2016-01-01 12:25:58 · 582 阅读 · 0 评论 -
URAL 1104(数论)
题目链接:URAL 1104解题思路: 思路就是简单的模运算规则:( a * b ) % c = ( ( a % c ) * (b % c ) ) % c 根据上述规则,有如下规律:( a * b^n ) % ( b - 1 ) = a % ( b - 1 ) 所以只要所有位上数字之和为b-1的倍数即可。代码:#include <cstdio>#include <cstring>#incl原创 2015-09-28 22:42:02 · 497 阅读 · 0 评论 -
数论之欧几里德算法(四)
简介:欧几里德算法的应用题目链接:poj 1061解题思路: A = m - n , B = y - x , N = L , 题目转化为求解模线性方程Ak ≡ B(mod N) 预处理:若m小于n,交换m与n,x与y代码:#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using names原创 2015-07-19 20:23:51 · 604 阅读 · 0 评论 -
数论之欧几里德算法(三)
简介: 模线性方程,指形如:ax ≡ b(mod n) 的方程,在现实中有若干应用,例如在RSA公钥加密系统中的密钥查找。该方程可用扩展欧几里德算法求解,解的大小范围为[ 0 , n )。算法: 运用扩展欧几里德算法解模线性方程其实是基于群论的,在这里不再赘述,如果把解的区间限制在整数范围内,那么方程有无穷解或者无解。因为无穷解在实际中并没有太大作用,所以我们一般考虑区间[ 0 , n )。原创 2015-07-19 18:05:12 · 685 阅读 · 0 评论 -
数论之欧几里德算法(二)
简介: 扩展欧几里德算法,是重写欧几里德算法以计算出额外有用信息的一种形式。算法用于计算满足下列条件的整系数x与y: d = gcd(a , b) = ax + by实现: 根据GCD递归定理,我们有:gcd(a , b) = gcd(b , a%b),我们将使用该定理来推导扩展欧几里德算法: gcd(a , b) = ax + by gcd(b , a%b) = bX + (a%b原创 2015-07-19 13:38:12 · 875 阅读 · 0 评论 -
数论之欧几里德算法(一)
简介: 欧几里德算法,又称辗转相除法,是求解最大公约数的算法。定理: 欧几里德算法的理论支撑为GCD递归定理,下面介绍这个定理。 GCD递归定理: 对任意非负整数a和任意正整数b,gcd(a , b) = gcd(b , a%b)代码: 由上述定理,我们可以直接得出gcd函数的代码:int gcd(int a,int b){ return b==0?a:gcd(b,a%b);}扩原创 2015-07-19 13:05:16 · 1124 阅读 · 0 评论 -
匹配及其相关问题(三)
前言: 第二篇博客介绍了匈牙利算法解二分图最大匹配,这次我们需要应用这个算法来解决最小点覆盖与最大点独立问题。基本定理: 根据博客(一),我们有以下定理: 定理3:二分图中,无孤立点,点覆盖数=边独立数(匹配数) 定理8:无向图中,无孤立点,最小点覆盖集与最大点独立集互补 我们这次需要使用这两个定理来解决最小点覆盖与最大点独立问题。算法思路: 根据定理3,我们有点覆盖数等于匹配数,那么原创 2016-04-05 22:24:08 · 583 阅读 · 0 评论 -
强连通分量的tarjan算法应用(一)
题目链接:POJ 2186解题思路: 先用tarjan算法求出图中的强连通分量,再求出缩点后唯一的叶结点即可。代码:#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;int n,m,dfn[100005],low[100原创 2016-02-23 16:24:29 · 852 阅读 · 0 评论 -
UVA 10972(边双连通分量)
题目链接:UVA 10972解题思路: 这题的题意很简单,就是给一个无向图,然后要求我们把所有的边都变成有向边,然后再另外添加一些有向边,最终用最少的边把有向图变成强连通的。一眼看过去是懵比的,然而仔细一想,转化后的有向图强连通即原图边双连通啊,于是题目转化成添加最少的边把原图变成边双连通图。先跑一遍Tarjan算法后缩点统计度为0和1的结点即可。代码:#include <vector>#inc原创 2016-05-03 23:19:51 · 1108 阅读 · 0 评论 -
UVALIVE 4452(2-SAT变形)
题目链接:UVALIVE 4452解题思路: 题意大概这样,n个人对m个方案进行投票,每个人最多对m个方案中的4个投票,要么支持,要么反对,问是否存在一个最终决定,能够让每个投票人都有一半以上的建议被采纳。这题的题意有一个比较不清晰的地方,就是什么叫超过一半,其实就是投1个或2个方案的时候,全部建议都被采纳;投3个或4个方案时,最多一个建议没有被采纳。输出要求先判断是否存在满足要求的最终决定,在能原创 2016-05-04 20:10:00 · 829 阅读 · 0 评论 -
sicily 4424
题目链接:sicily 4424解题思路: 先找到符合lucky number位数要求最小的数,然后枚举所有可能性,最小的符合要求的数即为答案。枚举方法使用全排列的next_permutation算法思想,生成全排列中下一个数。代码:// Problem#: 4424// Submission#: 4734859// The source code is licensed under Crea原创 2016-05-28 16:07:18 · 683 阅读 · 0 评论 -
最小瓶颈路与次小生成树
简介: 最小生成树是图论里面一类经典问题,可以有很多种变形,其中最小瓶颈路和次小生成树就是两种比较经典的变形。最小瓶颈路就是在两个结点之间求一条最长边最短的路径,而次小生成树则是所有生成树中权值排名第二的生成树(可以和最小生成树相等)。下面我们分别来看看这两个问题。最小瓶颈路: 给定一个加权无向图,并给定无向图中两个结点u和v,求u到v的一条路径,使得路径上边的最大权值最小。这个问题可以稍微加强原创 2016-05-06 14:00:41 · 7992 阅读 · 0 评论 -
匹配极其相关问题(一)
简介: 匹配问题是图论中一类非常经典的问题,最经典、常见的有二分图最大匹配和二分图最大权匹配,分别可以使用匈牙利算法与KM算法较高效解决。另外,匹配问题通常与支配集、覆盖集、独立集相关联,我们可以通过转化问题,将这些问题转化成匹配问题后套用算法解决。下面先介绍一些基本概念。基本概念: 匹配问题通常与支配集、覆盖集、独立集等问题相关,下面分别介绍五个基本概念。 1、点支配集: 对无向图G=(V原创 2016-04-05 11:09:13 · 826 阅读 · 0 评论 -
Tarjan三大算法之双连通分量(割点,桥)
Robert Endre Tarjan是一个美国计算机学家,他传奇的一生中发明了无数算法,统称为Tarjan算法。其中最著名的有三个,分别用来求解 1) 无向图的双连通分量 2) 有向图的强连通分量 3) 最近公共祖先问题 接下来几篇博客将分别讲述三个算法,首先是无向图的双连通分量,我们先从无向图的割点和桥讲起。下面介绍中无向图中割点和桥的概念: 割点:一个结点称为割点(或者割顶)当原创 2016-04-23 11:25:35 · 11459 阅读 · 4 评论 -
Tarjan三大算法之强连通分量
简介: 在之前的两篇博客中,我们详细介绍了Tarjan大牛发明的用来求解割点、桥和双连通分量的算法,这次我们介绍一下强连通分量。算法: 这次的Tarjan算法,可以用一次DFS把所有强连通分量找出来,依旧是用两个时间戳和栈来实现。算法的大体思路还是在深搜过程中更新时间戳,并将遍历过的结点保存在栈中,之后通过对时间戳的判断,来发现强连通分量。当我们完成对一个结点u以及其子孙的访问后,我们可以进行一原创 2016-05-07 22:21:41 · 1860 阅读 · 0 评论 -
Tarjan三大算法之双连通分量(双连通分量)
定义: 对于一个连通图,如果任意两点至少存在两条点不重复路径,则称这个图为点双连通的(简称双连通);如果任意两点至少存在两条边不重复路径,则称该图为边双连通的。点双连通图的定义等价于任意两条边都同在一个简单环中,而边双连通图的定义等价于任意一条边至少在一个简单环中。对一个无向图,点双连通的极大子图称为点双连通分量(简称双连通分量),边双连通的极大子图称为边双连通分量。这篇博客就是总结一下求解无向图原创 2016-05-03 16:18:43 · 21855 阅读 · 10 评论 -
sicily 1219(记忆化搜索)
题目链接:sicily 1214解题思路: 博弈题,用搜索来做。但是,如果用普通的搜索来做的话,是会超时的——复杂度大约是O( n^n ),所以需要采用记忆化搜索的方法(其实差不多就是动态规划了,但是这里是树形DP)。 状态: 用集合S表示现在树的状态,i 表示现在轮到谁进行砍边,dp[ S ][ i ]表示最优值。集合S可以用二进制来表示,即001表示现在还剩下第0条边。 状态转移: 1原创 2015-06-03 18:40:43 · 899 阅读 · 0 评论 -
sicily 1047(数学)
题目链接:sicily 1047解题思路: 题意很简单,即需要把一串连续的不超过25个的整数分成A、B两部分,分别相加得到两个数sumA、sumB,使得a+sumA=b+sumB。 一眼看过是感觉是0-1背包,但是其实不太一样,因为所有的整数是连续的,所以可以有更方便的方法解决。 假设第一个数为low,最后一个数为high,我们可以得到如下定理: 当A部分有 i 个数时,当且仅当(low+l原创 2016-05-01 16:04:48 · 621 阅读 · 0 评论 -
LightOJ 1422(区间DP)
题目链接:LightOJ 1422解题思路: 其实一眼看过去根本没想到是DP,而是画了一个连线图,即两个相同数字之间连一条直线,要求的其实是一个最长不交错序列。后来想到了一种对称的情况,例如样例为”5 1 2 3 2 1”,这样就没解了。但是也因为想到了这种情况,提醒了我这是一道区间DP的题目,于是解法就很简单啦。代码:#include <cstdio>#include <cstring>#i原创 2016-03-28 11:43:51 · 693 阅读 · 0 评论 -
匹配极其相关问题(四)
前言: 之前已经介绍了最小点覆盖与最大点独立,那么接下来就应该是最小边覆盖问题了。最小边覆盖问题有很多变种,其中最常见的就是DAG上的最小路径覆盖,这种问题可以转化成二分图最大匹配解决。基本定理: 根据博客(一),有定理如下: 定理4:二分图中,无孤立点,点独立数=边覆盖数=N-边独立数 若存在M个孤立点,上述定理3、4在顶点数N扣除M后成立。 定理7:无向图中,无孤立点, 1)若原创 2016-04-06 23:21:56 · 538 阅读 · 0 评论 -
URAL 1113(数学)
题目链接:URAL 1113解题思路: 这道题目其实是一类经典题目来着,是一道极限问题,即穿越沙漠问题,这种题目都是求在油箱容量受限的前提下,车辆如何走一段比较长的路的问题。一开始想没有想出来,后来看到这篇博客,就懂了。 这题为了使耗油量最小,很显然需要让车走最少的路程,因此必须每次启程,都能让油箱填满。所以可以使用倒推法进行求解,从最后一个油站开始,前一个油站总是要比后一个油站多储存等同于油箱原创 2016-03-01 08:54:09 · 661 阅读 · 0 评论 -
CSU_1216(异或最大值)
题目链接:CSU_1216题目简述: 经典题目,求一个数组中两个数异或运算的最大值。题目极其简单,但是要求的复杂度需要达到O(N * log(N)),还是比较难的。解题思路: 总的思路就是构建一棵0-1字典树,然后一个数让查找一个与其异或结果最大的数的效率达到O(log(N)),这里因为异或的特殊性质,可以使用贪心法则来实现。 1、0-1字典树: 这里其实是就是二叉树,之所以叫做字典树是因为原创 2015-12-20 23:19:56 · 9206 阅读 · 0 评论 -
UVA 11478(差分约束系统)
题目链接:UVA 11478解题思路: 题目要求使所有的边权值为正且尽量大,可以很自然地想到最大值最大化的经典解法——二分法。我们需要二分地去寻找答案,判断答案是否合理可以通过构建差分约束系统解决。 我们假设在第 i 个点上进行的权值操作为sum[i],那么所有 i 的出边都增加sum[i],入边都减少sum[i],因为每条边本身有权值,我们要满足权值增减之后所有边权为正,即满足等式sum[i]原创 2016-04-07 18:04:02 · 982 阅读 · 0 评论 -
差分约束系统(入门)
简介: 如果一个系统由n个变量和m个约束条件组成,其中每个约束条件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),则其为差分约束系统(system of difference constraints)。亦即,差分约束系统是关于一组变量的特殊不等式组。求解差分约束系统,可以转化成图论的单源最短路径问题。 观察xj-xi<=bk,会发现它类似最短路中的三角不等式d[v]<=d[u]+w原创 2016-03-04 12:08:06 · 811 阅读 · 0 评论 -
数论之欧拉函数
定义:欧拉函数φ(n),表示小于或等于n的数中与n互质的数的数目。 性质: 1) φ(1) = 1 2) 若n是质数p的k次幂,φ(n) = (p - 1)^(k - 1) 3) 若m, n互质,φ(m*n) = φ(m) * φ(n)原创 2015-11-06 22:51:05 · 1225 阅读 · 0 评论