基础算法
雪夜飞花
这个作者很懒,什么都没留下…
展开
-
二分查找
int bsearch(int A[], int l, int r,int a) { int m = (l + r) / 2; if (A[m] == a) return m; else if (A[m] > a) bsearch(A, l, m, a); else bsearch(A, m, r, a); return -1;}原创 2017-08-01 18:32:57 · 119 阅读 · 0 评论 -
最长公共子序列(DP)
dp[i][j]表示s串的前i个字符和t串的前j个字符的最长公共子序列 则当s[i]==t[j]时,dp[i+1][j+1]=dp[i][j]+1 当s[i]!=t[j]时,dp[i + 1][j + 1] = max(dp[i][j + 1], dp[i + 1][j]);char s[maxn],t[maxn];int n, m;int dp[maxn][maxn];void solve原创 2017-08-04 22:58:38 · 174 阅读 · 0 评论 -
种子填充(floodfill)
#define clr(a,x) memset(a,x,sizeof a)char a[100][100];pair<int, int> que[maxn];bool used[100][100];int n;void print() { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) {原创 2017-08-12 17:09:09 · 972 阅读 · 0 评论 -
全排列的求法(DFS)
A为输入的一组数 used用来标记A中第i个数是否已经被用过 perm数组用来存放已经生成的排列 DFS(x,n)是新的排列第x位的数int A[maxn];bool used[maxn];int perm[maxn];bool f = false;void dfs(int x,int n) { if (x == n) { for (int i = 0; i <原创 2017-08-04 18:22:11 · 291 阅读 · 0 评论 -
最长上升子序列(LIS)
问题描述:给出一个数列,找出这个数列中最长上升子序列中所包含的个数。 很容易能想到一个dp的方法: dp[i]=以i为末尾的最长上升子序列 但是该方法复杂度为O(n^2),我们发现上升子序列末尾的数字越小,它后面就越有优势,所以我们可以转而求在相同长度下,末尾元素的最小值。该算法的复杂度也为O(n^2),但因为dp数组是单调递增的,我们可以用二分的方法来进一步优化,这样时间复杂度就是O(n*l原创 2017-08-11 21:35:40 · 200 阅读 · 0 评论 -
01背包,完全背包,多重背包(O(V*n))
01背包有n种重量和价值分别为w[i]和v[i]的物品,每种各一个。从这些物品中挑选出总重量不超过W的物品,求所有挑选方案的价值总和最大值。思路:容易得到该问题的状态转移方程为dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]) 其中dp[i][j]表示从前i个物品中挑选出总重量不超过j的物品时总价值的最大值。int w[maxn];int v[maxn];原创 2017-08-10 22:50:51 · 596 阅读 · 0 评论 -
幂取模
可以每乘一次取一次模的方式来求一个数幂的模,时间复杂度为O(n),但是当n很大时,算法不是很理想,下面用分治的方法来求,其复杂度为O(logn)int pow_mod(int a, int n, int m) { if (n == 0) return 1; ll x = pow_mod(a, n / 2, m); int ans = x*x%m; if (n % 2原创 2017-08-03 19:32:16 · 399 阅读 · 0 评论 -
栈和队列
栈栈的操作: 1. push(x):插入数据 2. pop(x):弹出数据 3. top(x):获得栈顶数据 4. is_empty():判断栈是否为空 5. is_full():判断栈是否已满int s[maxn];int top=0;bool is_empty(){ return top==0;}bool is_full(){ return top>=原创 2017-08-10 21:19:10 · 139 阅读 · 0 评论 -
滑动窗口最值(单调队列)
问题:给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 解法:利用单调队列来保存未过期(在w窗口内)的之前的最大值,如果当前值大于该值,就从队首弹出,直到找到大于当前值得位置,将当前值的位置压入队首,如果数据过期,就从队尾删除。(单调队列)int a[maxn];int n;int w;deque<int> q;void solve() { for (int i =原创 2017-08-09 21:46:08 · 257 阅读 · 0 评论 -
大整数取模
设y为任意整数,x mod m=d 因为 (x*y) mod m =(x mod m)y=(x mod m)(y mod m)mod m 则有: y*(x mod m)=(y*d) mod m 将大数abcd分解为((((a*10)+b)*10+c)*10+d)然后从前向后求模即可int div_mod(char s[], int m) { int ans = 0; for原创 2017-08-03 01:30:15 · 508 阅读 · 0 评论 -
getMin功能的栈
stack<int> stackData;//存放栈数据stack<int> stackMin;//存放栈的最小值void push(int x) { stackData.push(x); if (stackMin.empty()) stackMin.push(x); else if (x < stackMin.top()) stackMin.push(x); el原创 2017-08-09 19:49:02 · 236 阅读 · 0 评论 -
GCD与LCM,extGCD
int gcd(int x, int y) { if (x < y) swap(x, y); while (y > 0) { int r = x%y; x = y; y = r; } return x;}int lcm(int x,int y){ return x / gcd(x, y)*y;}原创 2017-08-01 18:45:25 · 221 阅读 · 0 评论 -
快速幂的递归和非递归写法
int pos(int x,int n) { if (n == 0) return 1; int res = pos(x*x, n / 2); if (n & 1) res *= x; return res;}int pos(int x, int n) { int res = 1; if (n == 0) return 1; while (原创 2017-08-01 19:19:05 · 552 阅读 · 0 评论 -
分治法求RMQ
int findMaximum(int A[], int l, int r) { int m = (l + r) / 2; if (l == r - 1) return A[l]; else{ u = findMaximum(A, l, m); v = findMaximum(A, m, r); return m原创 2017-08-01 18:36:13 · 233 阅读 · 0 评论 -
并查集
int par[maxn];//父节点int deep[maxn];深度void init(int n) { for (int i = 0; i < 0; i++) { par[i] = i; deep[i] = 0; }}int find(int x) { if (par[x] == x) { return x;原创 2017-08-06 19:23:46 · 136 阅读 · 0 评论