上課內容
分治法,一開始講了三個證明遞迴複雜度的方法:
- 取代法:
三步驟:Guess, Verify, Solve
靠經驗假設,並驗證(加一些常數之類的) - 遞迴樹法
不太嚴謹,提供猜答案想法,最後用取代法驗證
畫出遞迴樹 - 主定理(Master Theorem)
比較f(n) 和 n^(logba)的關係
大於等於小於有三個複雜度
還有例題:
- 區間連續最大和
https://zerojudge.tw/ShowProblem?problemid=d784
中間切一半,max(左右最大值,跨過中間的最大值)
時間複雜度:O(NlogN)
有辦法O(n)? - 多項式乘法
Tioj 1064
FFT? (快速點的乘法)
Karatsuba algorithm,複雜度O(N^1.58),還可以用在矩陣乘法 - 平面最近點對
cf429D,Tioj
平面分治演算法很多都這樣做,先照x座標排序,中間切割:
max(兩點都在左邊、兩點都在右邊、跨過分割線答案)
求跨過分割線答案:照y座標排序,距離超過d的不要看,因為附近的點是有限個(最近點距離d),大概最多只需要看7個點,可以在常數時間看完所有點 - 尋找第k大
O(N)尋找第k大-利用分治
上機作業
逆序數對
題目連結
這是要求逆序數對的兩個數字的和,總共卡了兩個地方:
- TLE 計算和的複雜度爆了
- WA 數字溢位後爆了
第一點的解決方式:對於每一層利用O(N)的時間算前墜和
第二點的解決方式:每做完一個運算就mod 一次
1 |
|
好的序列
題目連結
題目簡單來說,就是給定n,要構造出一個1~n的序列,其中不包含3個數字以上的等差數列
解題想法: 我看不懂資芽的解法QQ
上網扣別人的扣,看幾乎都是同樣一個寫法,把奇數項的放前面,偶數項的放後面,之後不斷分治下去
直接實作然後AC ,於是我一直想到底要怎麼證明這個方法是正確的
於是我大概想到了一個上黑色白色的一個算合理的推倒吧
首先,我們把長度為$n$的序列分別交錯塗上黑白
再來,把長度為$n$的序列畫一條線分成$[1,\dfrac{n}{2}]$ 與$[\dfrac{n}{2}+1,n]$兩個序列,把奇數次項的數字放入第一個序列,再把偶數次項的序列放入第二個
我們可以發現,考慮橫跨中間線的兩邊是否有可能形成等差數列,可以發現是不可能,因為如果要橫跨兩邊,勢必要從一邊選出兩個,另一邊選一個,而同顏色的差為偶數,不同顏色的差必為奇數,因此不可能構造出橫跨兩邊的等差數列
但可以明顯發現,同一顏色是等差數列,其實只要分兩邊分別遞迴下去就可以了,遞迴處理完就是解答
遞迴直到長度為2時就可以return 了
程式碼:
1 |
|
王老先生有塊地喔
題目連結
這一題最需要關注的就是把問題縮小的關鍵
大範圍不會做,把規模縮到$2\times2$ 大小的方格總可以做了吧」
想辦法讓每一個$2\times2$ 大小的方格都有一格是被填滿的
剩下三格就很容易放進去
注意: 行跟列的維護很重要,一開始就要想好要怎麼樣定義儲存格,一維二維該放什麼
1 |
|
糟糕陣列
題目連結
其中一種構造方式:對於第i列第i行的「糟糕陣列」,必須滿足聯集為 ${1,2,…,2k-1}$的數字,我們可以先構造出2*2的糟糕陣列,把它複製到右邊(加上邊長)、右下、與下方(加上邊長,複製完之後因為會有重複一個數字,扣掉就好
1 |
|
手寫作業
增倍算法!
主要是介紹動態陣列,分析複雜度等等的東西
上一週的手寫作業被扣爆!