初识算法
文章平均质量分 74
clearriver
做一番一生引以为豪的事业;找一个一生荣辱与共的妻子;在有生之年报答帮助我的人;并且帮助有需要我帮助的人!
展开
-
每对顶点间的最短路径之一
这里给出的是基于动态规划方法,时间复杂度时O(v^4),可以通过“重复平方”计数使其复杂度降低位O(v^3*lgv).参考《算法导论》25.1#include using namespace std;const int N = 5;const int E = 9;const int MAX=0xffff;int g[N][N];/* * 这里l1代表“最多包含m-1原创 2009-09-13 11:25:00 · 939 阅读 · 0 评论 -
POJ 1321 棋盘问题(DFS+回溯)
这道题类似于八皇后问题,比较水。这里记下来是复习一下排列组合和回溯DFS。#include #include using namespace std;char g[9][9];int s[9][2];int count;int c;int f[9];bool check(int t){ int i = 0; int x = s[t][0];原创 2009-10-08 17:10:00 · 1363 阅读 · 0 评论 -
POJ 2251 (三维迷宫问题) DFS /BFS
这道题开始时用DFS做的,超时了,这也是意料之中的。后来改用BFS做AC。这道题时最基本的典型的搜索问题,通过DFS能够找到一个路径,但是不能保证是最优的,需要回溯搜索才能找到最优。通过BFS就能够找到一个最优解(如果存在),符合标准的BFS搜索。这里记录下来就为了作为搜索题的基础,以后能有所进步。#include #include #include using namespa原创 2009-10-09 09:52:00 · 2219 阅读 · 2 评论 -
POJ 2531(随机化思想)
题目大意:给一个完全图,求最大割。据说这是一个NP难的问题,我开始想的便是DFS+回溯,果然暴力搜索超时,后来参考别人的爆搜,进行了一些优化,竟然过了。用了400MS。可能有比较好的剪枝方法,可惜我没找到。这里主要笔记一下随机化算法,毕竟以前没有见到过。爆搜代码:#include #include using namespace std;int g[22][22];in原创 2009-10-09 22:09:00 · 1320 阅读 · 0 评论 -
POJ 2513 欧拉通路+并查集+trie树
#include #include using namespace std;const int max_size=500001;char s1[11],s2[11];int p[max_size];int r[max_size];int degree[max_size];int num=1;struct TreeNode{ int id;//the i原创 2009-10-13 20:20:00 · 1870 阅读 · 2 评论 -
POJ 1308 并查集判定“一个图是否为树”
判定一个图是否为树:方法一: 拓扑排序: (1)排除环的存在 (2)除了一个节点(root)其余各节点的入度为1.方法二: 并查集: (1)保证图是联通图(非森林) (2)保证不出现环和类似环(1->2,2->3,1->3),做法是对每个边进行合并原创 2009-10-13 22:08:00 · 1673 阅读 · 1 评论 -
trie树(字典树)介绍及简单实现
第一次接触trie树,翻了一些算法树竟然没有找到。于是在google上各种查找,现在对自己所了解的trie总结一下,以便将来复习,并给出简单的实现。Trie,又称字典树、单词查找树,是一种树形结构,用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。相对来说,Trie树是一种比较简单的数据结构.理解起来比较简单,正所谓简单的东西也得付出代价.故Trie树也有它的缺点,Tr转载 2009-10-13 14:28:00 · 1188 阅读 · 1 评论 -
并查集及其应用——kruscal法求最小生成树
并查集维基百科中是这样描述的:并查集是一种树型的数据结构,用于处理一些不相交集合(Disjoint Sets)的合并及查询问题。常常在使用中以森林来表示。(参考《算法导论》)并查集有以下基本操作:void make_set(int x):生成只包含x单个元素的集合int find_set(int x):查找包含元素x的集合“代表”(集合树中的根节点)void union_set(i原创 2009-10-13 17:38:00 · 1057 阅读 · 0 评论 -
后缀数组+最长公共前缀(LCS)+最长重复出现的不重叠字串(POJ 1743)
这几天一直在研究后缀数组,说实在,到现在还没有完全研究透。今天终于参考各种资料和代码,仿照别人的写出了一个求后缀数组和最长公共前缀的代码,记下来主要是为了将来复习。1,有关后缀数组的理论介绍就不介绍了,可以参考罗穗骞和许智磊两位大牛的论文。2,网上实现很多,但是我没有找到注释比较详细的实现,我这里主要结合代码给出详细的注释和需要注意的细节。 下面结合POJ 1743给出代码和注释原创 2009-10-17 14:58:00 · 3450 阅读 · 0 评论 -
POJ 2002 hash(枚举+哈希) 或者 枚举+二分
(zz)简单hash,具体做法是枚举任意两个点,因为有这由两个点所构成的边属于某个正方形那么可以计算出属于该正方形的另外两个点。如有两个点(a1,a2)和(b1,b2),那么如果点(a1+(a2-b2), a2-(a1-b1))和点(b1+(a2-b2), b2-(a1-b1))都存在则这四个点可以构成一个正方形。同时如果点(a1-(a2-b2), a2+(a1-b1))和点(b1-(a2-b2)转载 2009-10-06 20:33:00 · 1010 阅读 · 0 评论 -
POJ 1840 Hash 链地址避免冲突
差不多是第一次做HASH算法,今天用STL里的map和自己写的链地址避免冲突hash数组做POJ 1840,令人惊讶的是两种做法的效率竟然差了1300多MS (LT=5000MS),不知道是自己写的hash函数效率还行,还是STL太慢。下面的代码是自己写的hash函数:#include using namespace std;struct Node{ long num;原创 2009-10-06 16:04:00 · 1204 阅读 · 1 评论 -
每对顶点间的最短路径之二——floyd warshall
#include using namespace std;const int N = 5;const int E = 9;const int MAX = 0xffff;int ** g;/* * 函数返回Dn-1,其中Dk(i,j)表示顶点i到顶点j的“中间顶点都属于0,1,2,...,k”的最短路径p。 * 于是存在这样的子结构: * Dk(i,j) =原创 2009-09-13 15:17:00 · 968 阅读 · 0 评论 -
正整数n的k拆分问题
算法小菜鸟刚开始做POJ,1664是一个关于整数拆分的问题,即:将正整数n拆分成k个不能整数的和,0比如:将7差分成3个不同整数的拆分法有8中,其中1,1,5和1,5,1属于同一种拆分法。该问题等同于:将n个完全相同的物品放到k个完全相同的容器中,求有多少种方法。 由于小菜鸟数学不好,感觉是用递推,但总是写不出正确的递推公式,于是google之:http://hi.ba转载 2009-09-28 11:35:00 · 7313 阅读 · 0 评论 -
ZZ 状态DP
题目链接:http://acm.pku.edu.cn/JudgeOnline/problem?id=2817题目主要用到的算法:状态空间dp题目描述: 这个题的意思是第一行给出case数N (1 Sample Input5 abc bcd cde aaa bfcde 0要求的是,按任意顺序排列这些单词,可以在单词前面加任意个空格,使得相邻的单词上下对应的字母数目最多,并输出最多是多少。Sa转载 2009-09-28 16:24:00 · 1426 阅读 · 1 评论 -
状态压缩DP POJ 1699解题报告
http://acm.pku.edu.cn/JudgeOnline/problem?id=1699今天在做POJ 1699时,明显感觉用DP可以解,但是始终找不到合适的状态方程和子结构。在discuss中看到有人讨论用“状态压缩dp”求解比较方便,于是花了一下午时间去查找状态dp的资料,在上一篇(zz)中看到了一篇讲解非常详细的介绍,于是就开始来分析POJ 1699。看到这一题的第一直觉是原创 2009-09-28 19:23:00 · 1476 阅读 · 0 评论 -
KMP字符串匹配C++代码实现
#include #include #include using namespace std;/** *计算next,其中next[0]=-1,next[1]=0; *next[j+1] = k+1 如果p[j]= p[next[j]] = p[k],这里k=next[j] k+1或者0 如果p[j]!=p[next[原创 2009-09-19 19:18:00 · 1386 阅读 · 0 评论 -
KMP字符串匹配算法
转自http://hi.baidu.com/chioyang/blog/item/e8b58f384f51f2c3d56225fb.html我们从一个普通的串的模式匹配算法开始讲起,这样你才能更深入的了解KMP算法及其优点。咱们先来看看普通的串的模式匹配算法是怎么进行比较的主串 (S) a b a b c a b c a c b a b 子串 (T)a b c a c (子串又被称转载 2009-09-19 16:05:00 · 737 阅读 · 0 评论 -
KMP算法中的next数组求解
KMP算法是在模式串的next数组基础上进行的,如何求解next数组就成了关键。next数组的求解和主串无关,只与模式串自身相关。则next[j]= -1, 当j=0时 Max {k|0 0,其他情况比如对于p[5]=c, next[5]=2,因为p0p1=p3p4,此时k=2。下面参考《数据结构》严蔚原创 2009-09-19 17:10:00 · 2290 阅读 · 0 评论 -
最大连续重复子串
问题描述:寻找一个字符串中的某个子串,它是由某个字符串"连续重复构成",求出“连续重复次数最多”构成的那个sub—字符串。如果存在多个结果,求出字典排序最小的一个。比如对于字符串abababcc,“ababab”是最大连续重复子串,其中“ab”重复次数是3。再比如:bbbaaa,问题的答案是“aaa”,”a“重复3次构成。虽然"bbb"也是由"b"连续三次构成,但是字典排序"aaa"原创 2009-10-18 16:49:00 · 1804 阅读 · 0 评论 -
最大流入门POJ 1273 Edmonds-Karp
http://acm.pku.edu.cn/JudgeOnline/problem?id=1273自己的第一个最大流程序,作个纪念。#include #include using namespace std;const int max_size = 210;long c[max_size][max_size];//容量long flow[max_size][max_si原创 2009-10-24 21:57:00 · 84 阅读 · 0 评论 -
POJ 1828
之所以记录下这道题,是因为自己看了别人的想法才做出来的,感觉还算比较典型的题,就是根据“多关键字”,求出最大的元素。这里的最大是指存在一个关键字是最大的。 #include #include #include #include using namespace std;int p[50001][2];int cmp(const void *a,const void *原创 2009-11-01 20:59:00 · 614 阅读 · 0 评论 -
POJ 1451 字典树+DFS + 剪枝
#include #include #include #include #include using namespace std;struct TNode{ int num; TNode * next[26]; TNode() { num=0; memset(next,0,sizeof(next)); }};in原创 2009-12-17 18:16:00 · 1045 阅读 · 0 评论 -
POJ 1724 花销限制的最短路径
题意:在图中寻找一条从节点1到节点n的路径,在保证花销的前体下,使得路径最短。题解:1,使用dfs,超时,不会优化。2,使用优先级队列+BFS能保证得到一个最优解。下面是BFS的代码#include #include using namespace std;struct node{ int id; int len; int cost; bool原创 2009-12-20 00:27:00 · 911 阅读 · 0 评论 -
中位数的应用—士兵站队问题
pku 1723——士兵战队问题DescriptionN soldiers of the land Gridland are randomly scattered around the country. A position in Gridland is given by a pair (x,y) of integer coordinates. Soldiers c转载 2010-03-08 20:13:00 · 3003 阅读 · 4 评论 -
合并有序子数组
问题:子数组a[0:k-1]和a[k,n-1]已排序,将这两个数组合并为一个有序的数组,要求时间复杂度为O(n),并且只能用O(1)的空间复杂度。#include //int a[11] = {2,4,5,9,19,1,2,3,4,10,11};int a[11] = {1,2,3,4,5,6,7,8,9,10,11};int k=5;int n = 11;int bin_原创 2010-03-12 10:23:00 · 1229 阅读 · 0 评论 -
递归排列和字典序排列
递归排列和字典序排列全排列算法有两个比较常见的实现:递归排列和字典序排列。(1)递归实现从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递归处理,从而得到所有元素的全排列。算法实现如下: private static void perm(int nt,String[] permu) { // TODO Auto-gene转载 2010-03-08 21:41:00 · 931 阅读 · 0 评论 -
双调旅行商问题
from: http://blog.csdn.net/fangxia722/archive/2008/10/10/3051450.aspx一问题描述: 货郎问题(Traveling Salesman Problem,简称“TSP”)也叫货郎担问题,中国邮路问题,旅行商问题等,是计算机算法理论历史上的经典问题。在过去几十年中,它成为许多重要算法思想的测试平台,同时也促使一转载 2010-03-16 08:40:00 · 1370 阅读 · 0 评论 -
找到符合条件的整数
(编程之美)问题:任意给定一个整数N,求一个最小的正整数M(M>1),使得N*M的十进制表示形式里只有1和0.#include #include int n;int m[100];int main(){ scanf("%d",&n); int i =0; int j=0; int k = 0; int count = 0原创 2010-04-09 13:28:00 · 634 阅读 · 0 评论 -
二叉树的遍历(非递归)
#include #include using namespace std;struct TNode{ char data; TNode * lc; TNode *rc; bool flag; TNode () { data = /0; lc = rc = NULL; flag = false; }};原创 2010-04-17 15:01:00 · 689 阅读 · 0 评论 -
POJ 1338 Ugly Number
官方题解如下:{我们在数组hum中计算出前n个丑数。为了实现起来更简单,我们把1也作为一个丑数,算法也要因此略微调整一下。当我们已知前k个丑数,想得到第k+1个,我们可以这样做:对于每个质数p 寻找最小的丑数h 使得 h * p 比上一个丑数大 取我们找到的 h * p 中最小的一个:它就是下一个丑数为了使搜索更快,我们可以为每个质数维护一个索引“pindex原创 2009-12-15 22:43:00 · 1274 阅读 · 1 评论 -
0-1背包问题递归和非递归实现
0-1背包问题:求:从1,2,3,。。。n中取若干个数,使和为m,输出所有序列的非递归算法,其中,m>n#include using namespace std;const int M = 100;int num;int st[M];//保存合理解int a[5]={1,3,5,4,2};//物件重量int top;void find1(int s,int n)原创 2009-12-08 18:10:00 · 2222 阅读 · 0 评论 -
回溯——排列组合问题
排列组合与回溯算法KuiBing感谢Bamboo、LeeMaRS的帮助[关键字] 递归 DFS[前言] 这篇论文主要针对排列组合对回溯算法展开讨论,在每一个讨论之后,还有相关的推荐题。在开始之前,我们先应该看一下回溯算法的概念,所谓回溯:就是搜索一棵状态树的过程,这个过程类似于图的深度优先搜索(DFS),在搜索的每一步(这里的每一步对应搜索树的第i层)中产生一个正确的解,然后在以后的每一步搜索过转载 2009-11-21 00:46:00 · 998 阅读 · 0 评论 -
随机抽样问题(蓄水池问题)
【问题】随机抽样问题表示如下:要求从N个元素中随机的抽取k个元素,其中N无法确定。这种应用的场景一般是数据流的情况下,由于数据只能被读取一次,而且数据量很大,并不能全部保存,因此数据量N是无法在抽样开始时确定的;但又要保持随机性,于是有了这个问题。所以搜索网站有时候会问这样的问题。这里的核心问题就是“随机”,怎么才能是随机的抽取元素呢?我们设想,买彩票的时候,由于所有彩票的中转载 2009-11-21 10:49:00 · 6930 阅读 · 6 评论 -
线段树基础
在自然数,且所有的数不大于30000的范围内讨论一个问题:现在已知n条线段,把端点依次输入告诉你,然后有m个询问,每个询问输入一个点,要求这个点在多少条线段上出现过;最基本的解法当然就是读一个点,就把所有线段比一下,看看在不在线段中;每次询问都要把n条线段查一次,那么m次询问,就要运算m*n次,复杂度就是O(m*n)这道题m和n都是30000,那么计算量达到了10^9;而计算机1秒的计转载 2009-11-27 22:02:00 · 696 阅读 · 0 评论 -
子向量之和最接近0?
问题:给定一个浮点数向量a[]1~n],求子向量,使其之和最接近于0。 解答:初始化累加数组cum[i]=a[0]+...+x[i]。如果cum[k-1]=c[u],那么子向量a[k~u]之和则接近于0。于是问题转化为寻求符合条件的k和u。具体做法是排序cum数组,寻找相邻最小的cum[k]和cum[u],因此能够在O(nlgn)的时间内完成任务。 通过cum数组的应用还能够在原创 2010-01-24 15:20:00 · 724 阅读 · 0 评论 -
快速排序最坏情况下lgn的空间复杂度
《算法导论》上提到的:void quick_sort4(int *A,int l,int r){ while (lr) { int m=partition3(A,l,r); if (m(r-l+1)/2) { quick_sort4(A,l,m); l=m+1; } e原创 2010-01-25 11:12:00 · 2168 阅读 · 0 评论 -
离散化+线段树 POJ 2528 (Mayor's posters)
昨天开始接触线段树,感觉是很简单的数据结构,今天我发现我错了。今天从早上纠结到现在,一直在看线段树有关的问题,其中POJ 2401(线段树+并归排序)还没有解决。发现线段树非常灵活,要掌握好也非常难。在参考别人的基础上,做了POJ 2528。现在总结一下要点:1,离散化:题目中给出的海报长度范围时1~10000000,因此不可能建立一个如此大的线段树。而观察海报数量范围1~100原创 2009-11-28 15:47:00 · 893 阅读 · 1 评论 -
线段树 POJ 2352
这里主要想区别一下线段树和点数的区别:比如区间[0,7],点数的划分如下:[0,7]->[0,3]->[4,7]->...->[0,0],[1,1],[2,2]...[7,7],叶子节点是单个的点。创建代码如下:void build(int l,int r,int root){ tree[root].l=l; tree[root].r= r原创 2009-11-29 13:59:00 · 1182 阅读 · 0 评论 -
POJ 3368 Frequent values
题目大意:给定一个非递减的整数序列(n),然后给出m个查询区间,针对每一个查询,输出次去间内出现次数最多的“次数”。例如:n=10,m=3非递减序列:-1 -1 1 1 1 1 3 10 10 10查询序列:2 31 105 10则结果分别是:1,4,3。看到这道题,最直接的想法是针对每一个序列q(x,y),线性扫描统计区间x~y中每一数字出现的次数,求出最大值原创 2009-12-01 15:55:00 · 1279 阅读 · 0 评论 -
判断无向图是否存在环
http://www.blogjava.net/andyelvis/archive/2009/05/07/269304.html如果存在回路,则必存在一个子图,是一个环路。环路中所有顶点的度>=2。n算法: 第一步:删除所有度的顶点及相关的边,并将另外与这些边相关的其它顶点的度减一。 第二步:将度数变为1的顶点排入队列,并从该队列中取出一个顶点重复步骤一。转载 2010-05-18 18:40:00 · 2549 阅读 · 0 评论