
算法设计
mazheng1989
努力中。
展开
-
A算法解九宫格
以前写拼图游戏的时候就有个疑问:如果随机生成每个图片的位置的话,这个拼图可能是永远也解不出来的。但是当时不知道如何去解一个九宫格问题。 最近了解了一下搜索算法,发现其实很多很多的问题都可以归结为对状态空间树的搜索,搜出来最优解。但是问题的解空间往往是巨大的,超出了计算机的计算能力。搜的所称中如何减少向下搜索的分支非常重要。而启发式搜索算法,着重于先搜那些可能快速达到终点状态的分支,原创 2011-10-29 00:29:55 · 7306 阅读 · 0 评论 -
数组快速移位
//移位的时候,直接把一个元素放到它最终的位置上,但是要注意元素的下标是如何变换的。时间效率O(n),空间效率O(1).#include#includeusing namespace std;int gcd(int n,int k){ while(k) { int r=n%k; n=k; k=r; } return n;}int原创 2011-11-10 19:42:26 · 490 阅读 · 0 评论 -
差分约束系统+spfa算法 poj1201
先把问题转化为差分约束系统,然后把差分约束系统转化为满足条件的图,然后对图求最大(或者最小)路径。 Dijkstral和Bell-man Ford是求单源最大最小路径的方法。但是效率并不高。 spfa(shortest path fast algorithm)算法效率较高。因为,对于那些距离没变化的点v,以后也不可能通过v来使别的点u的路径发生变化。所以用一种记录的方式记录变化的点,没有变原创 2011-12-03 12:18:43 · 691 阅读 · 0 评论 -
矩阵相乘的最优顺序
对于一个矩阵,进行乘法的顺序不一样,总的元素的乘法次数也不同。我们希望给出一系列矩阵之后,能找到元素乘法次数最少的计算顺序。 用动态规划来求解这个问题。/* * ===================================================================================== * * Filename:原创 2011-12-01 11:46:51 · 3260 阅读 · 0 评论 -
网络最大流问题 poj1273 Drainage Ditches
网络最大流问题。 其实想法很直观,就是找一条流的路径,然后取这条路径上的最大流量,然后更新约束条件,然后再找这样的路径。。。直到没有能继续的路径。 找路径的方法使用的是广度优先搜索。 ps:最近在练习c语言,c语言虽然用起来比c++墨迹,各种注意事项,但是运行速度上跟c++的确不在一个量级上。15ms AC,源代码:/* * =======================原创 2011-12-07 10:18:04 · 675 阅读 · 4 评论 -
poj 2528 线段树
这道题,咋一看,似乎非常简单。开个数组记录每个小格子的位置是被谁占用了即可。但是注意到, 1 i 然后想到用链表表示每一段:每一次插入的时候就更改一下链表,最后统计链表中的不同的poster的个数。但是这种效率是O(n^2),而且需要大量对链表的操作,时间效率也不高。 后来想到,把所有的li,ri排个序,然后就会大大压缩表示数组的长度,效率将会提高到O(n^2), n=10000.原创 2012-02-17 22:31:36 · 535 阅读 · 0 评论 -
一个非常好的字符串Hash函数
int cal_key(char *key){ unsigned int h = 0; while (*key){ h = (h << 4) + *key++; unsigned int g = h & 0xf0000000L; if (g) h ^= g >> 24; h &= ~g; } return h原创 2012-03-04 20:43:30 · 670 阅读 · 0 评论 -
poj2352 Stars (第一道树状数组
树状数组详解 通过这道题,我对树状数组的理解: 树状数组通过一种类似与二叉树的结构,使得任意连续段的求和操作的时间复杂度为O(log(N)).但是付出的代价是,对某一个元素做修改的时候的时间复杂度不再是O(1),而是O(log(N)). 一般数组求某一连续段的和的时间复杂度为O(N),而树状数组为O(log(N)). 因此,树状数组适合于,需要大量经常计算某连续段的和的情原创 2012-03-25 22:51:10 · 558 阅读 · 0 评论 -
poj 3297Open Source 解题报告(附测试数据
昨晚看了一篇关于暴雪三重hash算法的文章,有意实践一下。 以前做字符串hash的时候想到过用另一个hash_key去区别同位置的字符串(用strcmp来比较两个字符串是否相等真的好慢),但是因为理论上不可能有hash_key可以唯一的让一个string区别与另一个string,所以一直认为这么做不可行。一直用开地址链表的方法做hash. 看完暴雪三重hash这个文章之后,感觉只要选择原创 2012-03-13 20:19:20 · 1144 阅读 · 3 评论 -
若干经典的字符串哈希函数
// RS Hash Functionunsigned int RSHash( char * str){ unsigned int b = 378551 ; unsigned int a = 63689 ; unsigned int hash = 0 ; while ( * str) { hash = hash * a + ( * str ++ ); a *= b; }转载 2012-03-13 19:50:02 · 489 阅读 · 0 评论 -
poj 2195 带权重的二分图最大匹配问题
看了很长时间二分图的匹配,没怎么理解,带权重的就更不用说了。 但是既然看了这题,先给刷过吧。 粘的别人的模板,过了,心里很不爽,有空一定要好好读读《算法导论》的这个章节。#include#include#include #define MAXN 110#define inf 1000000000#define _clr(x) memset(x,0xff,sizeof(in原创 2012-03-17 13:45:53 · 3009 阅读 · 0 评论 -
poj 2051 (用Priority_queue求解
一开始就没有深刻理解,认为要做的事儿是: 设时间为p1,p2,...pn.则需要从 p1,p2,p3...pn; 2*p1,2*p2,2*p3...2*pn;... K*p1,K*p2,..K*pn;中找到最小的前K个。 这样的话最坏情况有10^7个数据,辛辛苦苦用了set ,qsort,priority_queue等方法均超时。 实在受不了了,看了一下别人的思路,是原创 2012-04-25 00:36:35 · 1420 阅读 · 0 评论 -
kmp浅解
kmp的详细算法解析参见Matrix67的博文kmp详解根据这个详解所写的kmp 的c语言实现:#include #include#define max_n 4005#define max_len 205int len1,len2;char str1[max_len],str2[max_len]; //str1为被匹配字符串,str2为patternchar str[ma原创 2012-05-31 12:05:03 · 598 阅读 · 0 评论 -
Rabin-Karp字符串匹配算法
Rabin-Karp是一个不错的字符串匹配算法。wiki Rabin-Karp理解之后,发现这种算法不仅在解决一维问题时十分有效,而且二维时也很不错。#include #include#define PRIME 999999#define max_n 4005#define max_len 205int len1,len2,len[max_n];//char原创 2012-05-31 13:47:47 · 1221 阅读 · 0 评论 -
poj 1159 动态规划
这是一道基本的动态规划题,可惜我连一个正确的dp方法都没想出来。惭愧。一直认为DP是几种编程思想里最难掌握的,“状态转移式子”很难总结出来。DP真的应该多练一练。这道题的两个思路:思路1:设min[i][j]表示字符串str[i~j]转化为对称串所需添加的最小字符数,则当str[i]==str[j]时,min[i][j]=min[i+1][j-1];否则,min[i][j]=1原创 2012-05-16 13:21:45 · 753 阅读 · 0 评论 -
字符串模式匹配(所谓的kmp)算法
#include#include#include#include#include#includeusing namespace std;inline unsigned __int64 getclock(){ __asm { rdtsc; }}const char Min='a';const int characters=26;原创 2011-11-10 19:45:34 · 412 阅读 · 0 评论 -
n个元素中找前m个高效率算法
//本算法的思想是把n个元素分为sqrt(n)组,每次从n组中找出最小的。当n>>m时,效率在O(n)级别。#include#include#includeusing namespace std;templatevoid FindMin(E *&arr,int left,int right){ E temp=arr[left]; int index=left原创 2011-11-10 19:38:45 · 514 阅读 · 0 评论 -
poj 1182 食物链
最近学算法学到并查集,感觉挺简单的。于是乎在poj里找相关的题目练练手,一做就懵了。即便知道这道题是用到什么数据结构去做,可是把一个实际问题抽象转化为学过的数据结构与算法的过程也还挺难的。然后参考别人的解题报告写出来了poj1182题。 总结并查集的用法如下: 一般来说,给定的问题都不可能像书本上的例子那样,直接让你求一些元素的并集,而是给定一些元素,其中某些元素发原创 2011-10-30 14:38:11 · 752 阅读 · 0 评论 -
哈密顿回路
图类:#include #include#include#include#includeusing namespace std;template //T为顶点的数据类型,E为图中边的权值的数据类型class Graph{private: static const int DefaultVertices=10; //默认最大顶点数 int maxVertices; /原创 2011-10-30 21:16:04 · 4845 阅读 · 0 评论 -
求连通图的割点
#include#includeusing namespace std;const int gray=1;const int white=0;const int black=2;const int v_num=10;const int start=0;int graph[v_num][v_num];int color[v_num];int Time;int discoverT原创 2011-11-19 15:26:10 · 520 阅读 · 0 评论 -
并查集
并查集C++代码:#include#include#includeusing namespace std;templateclass UFSet{private: int *parent; E* elements; int size;public: void input(E *e) { for(int i=0;i<size;i++) { elements原创 2011-10-30 12:26:57 · 446 阅读 · 0 评论 -
poj1276 cash machine
这道题是一个多重背包问题。 以前只是用二维数组,带记忆的递归做过01背包问题,做这个多重背包问题很费劲。 要想明白,一维数组如何能记录最优解,要想明白如何把多重背包问题转化为01问题。直接把不同个数的同一种物品看作一种物品的方法,会使得物品太多,解的效率很低。 网上有很多效率高的方法,一种是把多重背包,按二进制数分成不同的物品,从而减少物品个数。也就是把n个相同的物品,转换为log原创 2011-11-23 11:59:13 · 570 阅读 · 0 评论 -
最小生成树 prim算法
#include"Graph.h"#include#include#include#includeconst int MAX=std::numeric_limits::max();templatevoid prim(int vetex_num,Graph &myGraph){ int *visited=new int[vetex_num]; visited[0]=-1;原创 2011-11-03 21:21:31 · 506 阅读 · 0 评论 -
8种排序算法
// Temp.cpp : 定义控制台应用程序的入口点。//#include"stdafx.h"#define BestInsertSortLength 16#define Swap(a,b) (a)^=(b)^=(a)^=(b); #include#include#include#include#includeusing namespace std; inline原创 2011-11-03 21:23:41 · 923 阅读 · 0 评论 -
普通青年,文艺青年,二逼青年之程序员版
//普通青年版int add1(int a,int b){ return a+b;}//文艺青年版int add2(int a,int b){ return int (&(((char *)a)[b]));}//二逼青年版int add3(int a,int b){ return (a&b)?add3((a^b),(a&b)<<1):(a^b);}原创 2011-11-03 21:34:54 · 1231 阅读 · 0 评论 -
生成全排列
#include#include#include#include#includeusing namespace std;struct Node{ int i; int dept; Node(int id,int depth) { i=id; dept=depth; }};templatevoid permuta原创 2011-11-04 02:51:18 · 1270 阅读 · 0 评论 -
dijkstra 求最短路径
dijkstra算法写起来很容易,但是理解,证明它的正确性却不容易。#include"Graph.h"#include#include#include#includeusing namespace std;const int MAX=std::numeric_limits:: max();int main(){ ifstream cin("input.txt"); in原创 2011-11-04 18:55:42 · 378 阅读 · 0 评论 -
kruscal求最小生成树
#include"Graph.h"#include#include#include#includeusing namespace std;const int MAX=std::numeric_limits:: max();struct Edge{ int v1; int v2; int weight; };inline int cmp(const void *p1,原创 2011-11-04 21:16:52 · 383 阅读 · 0 评论 -
字符串模式匹配
#include#include#include#include#include#includeusing namespace std;inline unsigned __int64 getclock() { __asm { rdtsc; }}const char Min='a';const int characters=26原创 2011-11-05 15:48:09 · 385 阅读 · 0 评论 -
avl树
#include#include#includeusing namespace std;templatestruct AVLNode{ int bf; //ÆœºâÒò×Ó balance factor AVLNode *leftchild; //leftchild AVLNode *rightchild; //rightchild E data;原创 2011-11-08 00:27:04 · 484 阅读 · 0 评论 -
生成一个序列的全排列
之前写过全排列的程序,昨天做poj 1731的时候又遇到了。发现自己以前把各个方法基本都试过了 。这里总结一下下面几种方法:方法一:把全排列转换为树的遍历,可以使用深度优先遍历,也可以使用广度优先遍历(需要存储大量中间数据,内存要求大)。具体实现可以用递归,也可用非递归。方法二:根据当前的排列,交换元素,生成下一个,然后再生成下一个。。。。。。比如有个字符序列acdef,当前排原创 2012-05-26 07:39:31 · 1363 阅读 · 2 评论