你可以把所有蛋糕依照好吃度 與價錢 的比值,由大到小排序。
接著依序拿蛋糕直到錢不夠為止。
時間複雜度為排序的 。
實作上需要特別注意一些問題:
inf
所以不太會出問題,如果題目改成蛋糕不可分割的話,這種依照 CP 值的 greedy 方法是不行的,
詳細原因與解法會在第七週的課程教到,如果有興趣的話可以先自己想想看為什麼。
題目要求你將 分解為 個二的幂次,其實就是單純的二進制分解而已,我們可以很容易的知道下面兩種情況會無法分解。
1
的個數大於 時也會無法分解,因為能夠分解的最少數字,其數量已經大於 了。而剩下就是如何分解而已,這邊我們利用 priority queue 可以自動找出最大值的功能,先將 做二進制分解並將分解出來的數字都放進 pq
裡,如果數量小於 的話就從 pq
取出最大的數除以 ,生成兩個數字,並且放回 pq
,這樣做一次可以使得 增加 ,如此只需要一直重複直到 。時間複雜度為 priority queue 單次操作的 乘上總操作次數 ,複雜度為 。
總複雜度為分解 的 加上後面 priority queue 的 ,因此為 。
下方的解法 2 是複雜度 的做法,比起上面的解法又更快了一點,有興趣的可以自己研究看看。
因為這個子任務 最大只有到 ,因此我們可以直接枚舉所有可能的長度為 的子序列,並算出當中有多少是 BNT。
我們枚舉所有的 N,對於每個找到的 N,若左邊有 個 B 以及 個 T,從左邊任意取一個 B 再從右邊任意取一個 T 就可以組成一個 BNT 子序列,因此對於這個 N,我們可以得到 個 BNT 子序列。
我們定義一個長度為 的陣列 ,每個元素代表的意義如下:
因此我們只要把 從左到右跑一次,並且維護 的元素,最後的 就是我們要的答案。
維護方法:
- 每個 N 都可以接在目前遇到的 B 的後面,形成 個 BN
- 每個 T 都可以接在目前遇到的 BN 的後面,形成 個 BNT
要注意答案可能會超出 int
的範圍,因此型別需要設為 long long
。
設 表示上限為 且長度為 的遞增數列個數
首先觀察到,長度 可由長度 的遞增數列推得,其關係式為:
例如 的遞增數列 可分為
觀察得知 有以下關係式
將尾端 設為 時, 的可能數為 ;
將尾端 設為 時, 的可能數為
所以欲求 ,
只需要依序將 求出來,
再將 求出來,
依此類推,就能得到題目所需的目標答案
實作上由於結果相當龐大,做加法時會除餘要求的 如 a = (b + c) % 1000000007
並且設邊界 ,因為 的時候只有一種可能
個格子任選 個格子,令未選到的格子為隔板
選到的格子填上數字,規則如下:
例如 的格子為 _,_,_,_
,有以下可能選法:
|,_,_,_
_,|,_,_
_,_,|,_
_,_,_,|
其中 |
表示隔板 (未選到的格子)
根據規則將選到的格子填上數字:
|,2,2,2
1,|,2,2
1,1,|,2
1,1,1,|
格子選法數剛好為遞增數列的可能數,可用排列組合的計算方式算出
這題有兩個要點需要注意:
超越
本題可以使用 的複雜度實作