introduction
-
the master method
T(n) = aT(n/b)+f(n)<其中a>=1,b>1,f(n)為漸近正函數(shù)>
f(n) = O(n<sup>log<sub>b</sub>a-ε</sup>),T(n)=O(n<sup>log<sub>b</sub>a</sup>)
f(n) = O(n<sup>log<sub>b</sub>a</sup>\*log<sup>k</sup>n),T(n)=O(f(n)\*logn)
f(n) = O(n<sup>log<sub>b</sub>a+ε</sup>),T(n)=O(f(n))
divide and conquer
-
Tower of Hanoi
-
code
hanoi(n-1,A,C,B); move(n,A,B); hanoi(n-1,C,B,A);
-
time complexity:
M(1)=1
M(n)=2M(n-1)+1=2[2M(n-2)+1]+1=2n-1
O(n)=2n
-
-
MergeSort
-
recursion
mergesort(left,right,**a){ if(left<right){ int mid = 1/2(left+right); mergesort(left,mid,**a); mergesort(mid+1,right,**a); merge(a,b,left,right); copy(a,b,left,right); } }
-
nonrecursion
void merge_sort(int *list, int length){ int i, left_min, left_max, right_min, right_max, next; int *tmp = (int*)malloc(sizeof(int) * length); for(i=1;i<length;i*=2){ right_min = left_max = left_min+i; right_max = left_max+i; if(right_max>length){ right_max = length; } next = 0; while(left_min<left_max&&right_min<right_max){ tmp[next++] = list[left_min]>list[right_min]? list[right_min++]:list[left_min++]; } while(left_min < left_max){ list[--right_min] = list[--left_max]; } while(next>0){ list[--right_min] = tmp[--next]; } } }
-
time complexity:
T(n)=2T(n/2)+cn
O(nlogn) -
space complexity:
O(n)
-
-
Strassen’s matrix multiplication
-
the divide and conquer of matrix
-
T(n) = 8(T(n/2))+O(n<sup>2</sup>)
-
QuickSort
-
code
int Partition(Type a[],int p,int r){ int j=p; int j=r+1; Type x=a[p]; while(true){ while(a[++i]<x&&i<j); while(a[--j]>x&&i<j); if(i=j) break; swap(a[i],a[j]); a[p]=a[j]; a[j]=x; return j; } } void quiclSort(Type a[],int p,int r){ if(p<r){ int q=Partition(a,p,r); quickSort(a,p,q-1); quickSort(a,q+1,r); } }
-
time complexity:
Best case: split in the middle — Θ(nlogn)
Worst case: sorted array! — Θ( n2)
Average case: random arrays — Θ(nlogn)
-
-
linear time selection
- 只要不是選到了首尾,O(n)
Dynamic Programming
-
Fibonacci series
+ 列通項公式.png)
-
Matrix-chain Multiplication
-
code
void MatrixChain(){ int p[6] = {20,25,10,5,15,20}; int n = 5; int m[10][10]; int s[10][10]; int j = 0; for (int i=1; i<=n; i++){ m[i][i]=0; };//單個矩陣的計算量 for (int r=2; r<=n; r++){//r為每次循環(huán)矩陣鏈的長度 for (int i=1; i<=n-r+1; i++){ j=i+r-1; //設(shè)置初始值為從第一個元素進行斷開 m[i][j]= m[i+1][j] + p[i-1]*p[i]*p[j]; //設(shè)置初始斷開位置 s[i][j]=i; for (int k=i+1; k<j; k++){ //當前k值計算得到的值 int t= m[i][k]+ m[k+1][j]+p[i-1]*p[k]*p[j]; /*替換找到最小值*/ if (t< m[i][j]) { m[i][j]=t; s[i][j]=k; } } } } }
-
analysis
- 分析最優(yōu)解結(jié)構(gòu):M(1,n)=M(1,k)+M(k+1,n)+P0PkPn
(P0PkPn類型為兩個矩陣相乘所需的計算步驟) - 1.初始化矩陣鏈的對角線位置元素
M[a][a]=0
- 2.確定矩陣鏈長度
for(r=2;r<n+1;r++)
- 3.用i表示起始位置,j表示終止位置
for(i=1;i<n+1-r;i++),j=i+r-1
- 4.M(i,j)=M(i,k)+M(k+1,j)+PiPjPk,循環(huán)k的值
for(k=i+1;k<j;k++)
→找到最大值,并將k的值記錄下來,存儲到**t中
- 分析最優(yōu)解結(jié)構(gòu):M(1,n)=M(1,k)+M(k+1,n)+P0PkPn
-
-
0-1 Knapsack Problem
-
code
void KnapSack(){ int w[4] = {2,1,3,2};//物品重量 int v[4] = {12,10,20,15};//物品價值 int c = 5;//背包容量 int n = 4;//物品個數(shù) int m[c][n];//初始化矩陣 int jMax = 0; if(w[n]-1>c){ jMax=c; }else{ jMax=w[n]-1; } //使剛開始到最小容量的值直接為0 for(int j=0;j<=jMax;j++){ m[n][j] = 0; } for (int j=w[n]; j<c; j++) { m[n][j] = v[n]; } for(int i=n-1; i>1; i--) { jMax = min(w[i]-1,c); //裝不下第i個物品的,直接繼承i+1的值 for(int j=0; j<=jMax; j++){ m[i][j] = m[i+1][j]; } for(int j=w[i];j<=c;j++){ m[i][j] = max(m[i+1][j],m[i+1][j-w[i]+v[i]); } } //最后的結(jié)果行不用計算之前復雜項了 m[1][c] = m[2][c]; if(c>=w[1]){ m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]); } } //判斷i和i+1的值相等否可以得出是否放了這個物品 Template<class Type> Void Traceback(Type **m,int w,int c,int n,int x) { for(int i=1;i<n;i++) if(m[i][c]==m[i+1][c]){ x[i]=0; }else{ x[i]=1; c-=w[i]; } x[n]=(m[n][c])?1:0; }
-
analysis
- m[i][j] = max(m[i+1][j],m[i+1][j-w[i]+v[i]]);
- 判定m(i,c)與m(i+1,c)的值是否相等來確定x(i+1)是否為1;
-
-
Optimal Binary Search Trees
-
binary search tree
e[i,j] = min(e[i,r-1]+e[r+1,j]+w(i,j))
-
Greedy Algorithms
Backtracking
-
Loading Problem
-
analysis
按深度優(yōu)先先進行一條線路的遍歷,到達底部后重新回溯生成最優(yōu)解,進行比較到最后生成最后的解
-
-
0-1 knapsack problem
-
analysis
最優(yōu)解的限界為裝入盡可能多的物品,并且將最后一部分物品只裝入部分產(chǎn)生的限界.
-
time complexity
O(n2n)
-
Graph m coloring problem
-
Branch and bound(在約束條件下找出一個最優(yōu)解)
-
Loading Problem
-
code
if(Ew+w[i]<=c){ AddLiveNode(H,E,Ew+w[i]+r[i],true,i+1); } AddLiveNode(H, E, Ew+r[i], false, i+1); HeapNode<Type> N; H.DeletMax(N); i = N.level; E = N.ptr; Ew = N. uweight – r[ i -1 ];
-
anlysis
節(jié)點的左子樹表示將此集裝箱裝上船,右子樹表示不將此集裝箱裝上船。
設(shè)bestw是當前最優(yōu)解;Ew是當前擴展結(jié)點所相應的重量;r是剩余集裝箱的重量。
則當Ew+r≤bestw時,可將其右子樹剪去,因為此時若要船裝最多集裝箱,就應該把此箱裝上船。
-