第一章
第二章
//非递归
int quick_pow(int a,int b){//a^b
int cnt = 1;
while(b){
if(b&1) cnt *=a;
a*=a;
b>>=1;
}
return cnt;
}
//递归
int quick_pow(int a,int b){//a^b
int cnt = 1;
if(b){
cnt = quick_pow(a,b/2);
cnt *= cnt;
if(b&1) cnt*=a;
}
return cnt;
}
//O(logn)
void hmove(char a, char b, char c, int n){
if(n == 0){
return ;
}
hmove(a, c, b, n - 1); //前n - 1块从a移动到b上
printf("%c -> %c\n", a, c); //我自己移动一块从a -> c
ans++; //我移动了几次?
hmove(b, a, c, n - 1); //最后把 n - 1块从b移动到c上
}//f(n) = 2f(n-1)+1;
//只能先移动到相邻的柱子上
void hmove2(char a, char b, char c, int n){
if(n == 0){
return ;
}
hmove2(a, b, c, n - 1); //把前n - 1块通过b移动到c上
ans2++; //把最后一块移动到b上
printf("%c -> %c\n", a, b);
hmove2(c, b , a, n - 1); //把n - 1 块通过b移动到a上
ans2++; //把最后一块移动到c上
printf("%c -> %c\n", b, c);
hmove2(a, b, c, n - 1); //把剩下的n - 1块通过b移动到c上
}//f(n) = 3f(n-1)+2;
int find_2(int l,int r,int x){
int m;
while(l<r){
m = (l+r)>>1;
if(a[m] < x) l = m+1;
else r = m;
}
return l;
}//O(logn)
``
第三章
第四章
第五章
回溯算法:是一种选优搜索法,按选优条件向前搜索,以达到目标。回溯法采用试错的思想,它尝试分步的去解决一个问题。在分步解决问题的过程中,当它通过尝试发现现有的分步答案不能得到有效的正确的解答的时候,它将取消上一步甚至是上几步的计算,再通过其它的可能的分步解答再次尝试寻找问题的答案。
使用回溯算法对于问题的解空间进行深度搜索时,通常有两种搜索算法:递归回溯、迭代回溯。
递归回溯:使用递归函数对于解空间进行DFS的回溯算法
0/1背包问题 DFS.
上界函数 用于剪除不包括最优解的子树
完全子图:给定无向图 G(v,e) U(v’,e’)当v’属于v,e’属于e,且对于图U任意两个节点都可以直接相连,U是G的完全子图,也可以说图U是图G的一个团体当且仅当图U不包括在更大的完全子图中时。
图G的最大团体指的是包含图G节点数最多的团体
找到最大团体算法 DFS
第六章
第七章
1是源点 M是汇点,朴素EK
void EK(){
19 //从1出发,不断找可以到达m的增广路
20 int ans = 0;
21 while(true){
22 //EK算法的核心是通过bfs不断查找增广路,同时建立反向弧
23 //每次循环都要对v数组和p数组进行清空,因为是意图查找一条新的增广路了
24 memset(p, 0, sizeof(p));
25 memset(v, 0, sizeof(v));
26 queue<int> q;
27 q.push(1);
28 v[1] = INF;
29 //每次只找一条增广路,同时修改c[i][j]的值
30 while(!q.empty()){
31 int f = q.front();
32 q.pop();
33 for(int i = 1; i <= m; i++){
34 if(v[i] == 0 && c[f][i] > 0){ //v[i]原本是记录增广路实时的残量最小值,v[i]==0代表这个点还没有走过,且从p到i的残量大于0说明通路
35 v[i] = min(v[f], c[f][i]); //实时更新v[i]的值,v[f]存储1条增广路中i点前所有水管残量的最小值,v[i]为该条增广路到i点为止,路径上的最小残量
36 p[i] = f; //p[i]实时保存i点的前驱节点,这样就当i==m时整条增广路就被记录下来
37 q.push(i); //将i点入队
38 }
39 }
40 }
41 if(v[m] == 0) break; //如果v[m]==0则代表找不到增广路了(中途出现了c[i][j]==0的情况)
42 ans += v[m];
43 int temp = m;
44 while(p[temp] != 0){ //类似并查集的查操作,不断查上一个元素且将剩余残量减去最小残联,反向弧增加最小残量
45 c[p[temp]][temp] -= v[m];
46 c[temp][p[temp]] += v[m];
47 temp = p[temp];
48 }
49 }
50 printf("%d\n", ans);
51 }