前言
$Master$定理,又稱主定理,用於程序的時間復雜度計算,核心思想是分治,近幾年$Noip$常考時間復雜度的題目,都需要主定理進行運算。
前置
我們常見的程序時間復雜度有:
$O(n)/O(n2)/O(nlog_2n)/O(2n)$等等...
我們叫它程序的漸進時間復雜度,例如一段程序執行這樣的循環:
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sum+=a[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
pai*=a[i][j];
顯然,這段代碼一共運行了$n3+2n2$次,我們將它的漸進時間復雜度寫作$O(n3)$,即保留最高項但忽略其系數,約定:一般我們將$log_2n$寫作$logn$,將$logn*logn$寫作$log2n$
算時間復雜度有什么用呢?一般來說,在比賽時我們將知道程序的時間限制,一般為$1s$,我們可以通過粗略計算程序時間復雜度來判斷程序是否能在$1s$通過,否則會$TLE$。
時間復雜度 | $1s$內穩過的范圍 | 極限范圍(危險) |
---|---|---|
$O(1)$ | $\infty$ | $\infty$ |
$O(wys)$ | $\infty$ | $\infty$ |
$O(logn)$ | $\infty$ | $\infty$ |
$O(n)$ | $5\times10^7$ | $10^8$ |
$O(nlogn)$ | $5\times 10^5$ | $10^6$ |
$O(n^2)$ | $5000$ | $10000$ |
$O(n^3)$ | 300 | 500 |
$O(2^n)$ | 25 | 27 |
$O(n!)$ | 11 | 11(穩過) |
$O(n^n)$ | 8 | 8(穩過) |
PS:由於程序存在常數因子,極限范圍不一定能過,除非你是歐洲人。
大概來說,如果你算出的漸進時間復雜度量化后在千萬級別[$n\times10^7$],基本上是很穩的
對於非遞歸程序時間復雜度的運算方法,比較簡單粗暴的方法是數循環。但這種方法並不一定始終正確,如$NOIP2017PJT4$的二分答案是$O(logn)$復雜度的,$dp$的轉移是執行$n$次的,而對於單調隊列,每個元素至多進隊一次,出隊一次,最多與$2n$次操作,$dp$的總操作次數應該是將它們加在一起,共$3n$次操作,時間復雜度為$O(n)$,而不是$O(n^2)$,總復雜度為$O(nlogn)$,與之類似的還有$kmp$算法的時間復雜度。(PS:$kmp$算法的時間復雜度至今仍存在爭議,我們一般將其視作$O(n)$的)
正文
介紹$master$定理前,首先要知道一個符號
- $T(n)$表示時間復雜度,可以這樣表示:$T(n)=$一個單項式,例如:
$T(n)=2T(n/2)+f(n)$
- $\Theta$ 讀音:$theta$,表示等於
- $O$ 讀音:$big\ oh$,表示小於等於
- $o$ 讀音:$small\ oh$,表示小於
- $\Omega$ 讀音:$big\ omega$,表示大於等於
- $\omega$ 讀音:$small\ omega$,表示大於
主定理是怎么表示的呢?
- 我們目前有一個規模為$n$的問題
- 通過分治,我們將問題分成$a$個規模為$\frac{n}{b}$,每次遞歸將帶來$f(n)$的額外計算
- 於是得到關系式:
$T(n)=aT(\frac{n}{b})+f(n)$
此外,我們還要定義一個$C_{crit}$,它是這樣計算的:
$C_{crit}=log_ba$
那么有:
$1$.
- 當$f(n)=O(nc)$,且$c<c_{crit}$時有:$T(n)=\Theta(n{c_{crit}})$
- 例子:
- $T(n)=8T(\frac{n}{2})+1000n^2$
- 此時$a=8,b=2,f(n)=1000n^2$
- 當$c=2$時,$f(n)=O(n^2)$
- 又因為$C_{crit}=log_ba=3>c$
- 所以$T(n)=\Theta(n{log_ba})=\Theta(n3)$
$2$.
- 當$f(n)=O(n^c)$,且$c>c_{crit}$時有:$T(n)=\Theta(f(n))$
- 例子:
- $T(n)=2T(\frac{n}{2})+n^2$
- 此時$a=2,b=2,f(n)=n^2$
- 當$c=2$時,$f(n)=O(n^2)$
- 又因為$c_{crit}=log_ba=1<c$
- 所以$T(n)=\Theta(f(n))=\Theta(n^2)$
$3$.
- 若存在一個非負整數$k$,使得$f(n)=\Theta(n{c_{crit}}logkn)$
- 那么$T(n)=\Theta(n{c_{crit}}log{k+1}n)$
- 例子:
- $T(n)=2T(\frac{n}{2})+10n$
- 此時$a=2,b=2,f(n)=10n$;$c_{crit}=log_ba=1$
- 當$k=0$時$f(n)=\Theta(n1log0n)=\Theta(n)$
- 所以$T(n)=\Theta(n1log1n)=\Theta(nlogn)$
練手題
- 首先,我們知道$a=2,b=4,f(n)=\sqrt{n}=n^{\frac{1}{2}}$;$c=\frac{1}{2},c_{crit}=log_42=\frac{1}{2}$
- 當$k=0$時,滿足條件3,所以,$T(n)=O(\sqrt nlogn)$,選$C$
$T(n)$
$=T(n-1)+n-1+n$
$=T(n-2)+n-2+n-1+n$
$=...$
$=T(0)+0+1+2+...+n-2+n-1+n$
$=1+\frac{n\times (n+1)}{2}$
$=O(n^2)$
選擇$D$
- 假設$g(i)$,為計算$F(i)$的次數,因為$F(i)=F(i-1)+F(i-2)$所以$g(i)=g(i-1)+g(i-2)$
- 因為$F(1)=g(1)=1,F(2)=g(2)=1$,所以$g(n)=F(n)$
- 則:
$T(n)=g(n)=F(n)=O(F(n))$
選擇$D$
完結
這和大家能夠平安過初賽!