数据结构和算法
ixiumu
这个作者很懒,什么都没留下…
展开
-
哈希
哈希用来查找,哈希的冲突处理,结构类似于线性表,也可以用来存储图,稀疏图,允许重边。插入到头部,效率高一些,但是顺序相反了。const int maxn = 110;const int maxm = 10010;int head[maxn], next[maxm];void init(){ for(int i = 0; i < n; ++i){ head[i] = -1;原创 2015-10-17 15:59:17 · 432 阅读 · 0 评论 -
最短路——Dijkstra
Dijkstra算法,不能处理负边负环,不连通时返回-1。使用优先队列可以优化——spfa,下一篇会介绍。const int maxn = 110;const int max_int = ~(1<<31);const int min_int = (1<<31);bool vis[maxn];int cost[maxn][maxn], dist[maxn];//[0,max_in原创 2015-10-19 11:01:35 · 567 阅读 · 0 评论 -
MST——Prime
和Dijkstra算法非常非常像,只有一点点不同,数组d的含义变了,之前是到s的距离,现在是到集合的距离,也是贪心算法。const int maxn = 110;const int max_int = ~(1<<31);const int min_int = (1<<31);bool vis[maxn];int cost[maxn][maxn], dist[maxn];//[0,m原创 2015-11-23 16:40:24 · 754 阅读 · 0 评论 -
最短路——Bellman-Ford
可以处理负边,负环。int dijkstra(int s){ for(int i = 0; i < n; ++i){ dist[i] = max_int; } for(int k = 1; k < n; ++k){ for(int i = 0; i < m; ++i){ int x = u[i], y = v[i]; if(dist[x] < max_int){原创 2015-10-21 10:46:06 · 491 阅读 · 0 评论 -
MST——Kruskal
最小生成树的另一个算法,需要用到sort排序,而且这个sort有点儿绕。而且需要检测连通的话需要多一些操作。const int maxn = 110;const int maxm = 10010;const int max_int = ~(1<<31);const int min_int = (1<<31);int p[maxn];int u[maxm], v[maxm], w[m原创 2015-11-23 20:05:54 · 493 阅读 · 0 评论 -
排序
//1.直接插入排序,稳定//很久以前就学过直接插入了,但是写起来还是出了挺多问题的void inssort(int *d, int s, int e){ for(int i = s+1; i <= e; ++i){ int x = d[i]; int j = i-1; while(j >= s && d[j] > x){ d[j+1] = d[j]; --j;原创 2015-11-20 19:42:16 · 677 阅读 · 0 评论 -
KMP
KMP算法是一种改进的字符串匹配算法KMP的核心在于NEXT数组。初始化next数组很巧妙,用next自己匹配自己,使得复杂的从m*m下降到m求next数组和kmp匹配的函数有相似之处暴力搜索复杂度m*n,KMP为m+n,效率很不错,不过在一些特定情况下kmp表现也会很糟糕,此处不做讨论。void init_next(char *t, int *next) {原创 2016-03-27 21:26:57 · 479 阅读 · 0 评论 -
二分查找
关于区间的选择,觉得还是闭区间优于左闭右开,选用闭区间。//[l, r]//相等的,找不到返回-1int bs1(int *d, int l, int r, int v){ while(l < r){ int m = (l+r)>>1;// printf("%d %d %d\n", l, r, m); if(v > d[m]){ l = m + 1; }else i原创 2015-11-19 10:18:02 · 415 阅读 · 0 评论 -
DFS
深度优先搜索递归,或者栈替代,实现比较复杂。原创 2015-10-28 10:34:47 · 470 阅读 · 0 评论 -
背包问题
来自著名的背包九讲,算是笔记吧。n件物品,背包体积V、质量U,物品体积a[i]、质量b[i]、价值c[i],求最大价值。1. 01背包一种物品只有一件,可选可不选f[i][v] = max(f[i-1][v], f[i-1][v-a[i]]+c[i])i 顺序,v 逆序,空间复杂度可以降低一维2. 完全背包每种物品无限多f[i][v] = max(f[i-1][v]原创 2015-10-31 11:21:02 · 472 阅读 · 0 评论 -
DP
状态,保存当前所有状态状态转移方程最优子结构,全局最优解包含局部最优解重叠子问题两种动机:利用递归的重叠子问题,进行记忆话求解,即先利用递归法解决问题,再利用重叠子问题转化成动态规划;把问题看作是多阶段决策过程。两种实现方式:递推(向前和向后)和记忆化搜索。如果需要记录选择、打印路径的话需要辅助数组。原创 2015-10-28 15:43:35 · 373 阅读 · 0 评论 -
并查集
const int maxn = 10010;int p[maxn];int find(int x){if(x != p[x]) p[x] = find(p[x]); return p[x];}int find(int x){return x == p[x] ? p[x] : p[x] = find(p[x]);}for(int i = 0; i < n; ++i){ p[i] =原创 2015-10-15 10:30:41 · 390 阅读 · 0 评论 -
字典树
利用公共前缀减少查询时间,节省内存静态分配,动态分配malloc次数太多,效率不行const int maxc = 26;const int maxn = 1000010;typedef struct trie{ int v; struct trie *next[maxc];}trie;trie mem[maxn];int alloc;void init(trie *原创 2015-10-16 11:32:38 · 526 阅读 · 0 评论 -
博弈论——2
去火柴问题,取完为败题目1:今有若干堆火柴,两人依次从中拿取,规定每次只能从一堆中取若干根,可将一堆全取走,但不可不取,最后取完者为胜,求必胜的方法。 题目2:今有若干堆火柴,两人依次从中拿取,规定每次只能从一堆中取若干根,可将一堆全取走,但不可不取,最后取完者为负,求必胜的方法。T,利他态,异或为0S,利己态,异或不为0孤单堆,仅有一根火柴充裕堆,大于一根火柴原创 2015-11-04 10:17:01 · 588 阅读 · 0 评论 -
博弈论——1
取完为胜P点,必败点N点,必胜点① 所有终结点都是必败点P。② 所有一步能走到必败点P的就是必胜点N。③ 通过一步操作只能到必胜点N的就是必败点P。这三条性质很重要,可以解释下面所有问题的解法。本文中解释略过,只给出解法。1.一堆,每次取若干个打表,从尾到头。2.巴什博奕(Bash Game)一堆,每次取1~m个打表,从尾到头,同上。或者,更简单的,原创 2015-11-04 10:16:41 · 509 阅读 · 0 评论 -
栈和队列
数组模拟实现。模板不熟,改为模板更好一些。class stack {private: int maxsize, t; int *s;public: stack(int n) : maxsize(n), t(0){ s = new int[maxsize]; } virtual ~stack(){ delete []s; } void push(int v){ s[原创 2015-10-23 19:41:18 · 309 阅读 · 0 评论 -
贪心
贪心策略,保证策略正确,每一步都是最优。如果不能保证每一步都是最优,可以选择保存所有状态,然后就转到DP了。原创 2015-10-28 10:38:47 · 375 阅读 · 0 评论 -
最短路——SPFA
Bellman-Ford基础上的队列优化,效率比较高,可以检测负环。const int maxn = 110;const int max_int = ~(1<<31);const int min_int = (1<<31);bool inq[maxn];int cost[maxn][maxn], dist[maxn], cnt[maxn], q[maxn], front, rear;原创 2015-10-27 15:12:13 · 397 阅读 · 0 评论 -
最短路——Floyd
求每两点之间的最短路。还有个有意思的用处,判断每两点之间是否有通路,初始值设为0或者1,d[i][j] = d[i][j] || (d[i][k] & d[k][j]),有向图的传递闭包。for(int k = 0; k < n; ++k){ for(int i = 0; i < n; ++i){ for(int j = 0; j < n; ++j){ if(d[i][k] !=原创 2015-10-27 15:30:57 · 356 阅读 · 0 评论 -
BFS
宽度优先搜索队列原创 2015-10-28 10:34:01 · 359 阅读 · 0 评论 -
回文
1.不连续的子串翻转一次,转化为求最长公共子序列(LCS),代码略,O(n^2)2.连续的子串①枚举start、end,判断是否回文,O(n^3)②枚举中点(分奇偶情况),向两边延伸,O(n^2)③后缀树,此处不予讨论④manacher算法,最高效的方法,O(n)充分利用了已经算出来的结果:对字符串预处理,逐位扫描,先利用前面基本确定p[i](以i为中心的最长回文串向一原创 2016-09-18 09:58:47 · 517 阅读 · 0 评论