<style> .reveal .slides { font-size: 32px; } </style> # NHDK TPR #17 (Div.1+2, Sponsored by YTP) 題解 --- ## 特別感謝 ---- ### AA 競程 ![](https://i.imgur.com/Xn4lg5v.png) ---- ### YTP 少年圖靈計畫 ![](https://i.imgur.com/NLjITye.png) ---- ### 驗題者們 sam571128、franklee1015、btlllbill、dreamoon、littlecube、Fysty、SFeather、wcwu、Darren、user1519、KTK2538、amano_hina --- ## A ### [Colten 的撞球對決記 (Pool)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/A) AC: 38 First Kill: Paul Liao ---- 給定兩隊的隊員 球第 $q$ 次是誰上場 ---- 子題 1 (20):$n+m = 2$ ---- 判斷奇偶,奇數就是第一隊,反之第二隊 ---- [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/A.%20Pool/Koying_sub1.cpp) ---- 子題 2 (80):無額外限制 ---- 將只有一人的隊伍變成有兩個一樣的隊員 然後判斷兩次奇偶 ---- [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/A.%20Pool/Koying.cpp) --- ## B ### [豪邁大笑的Koying (Laughing Koying)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/B) AC: 39 First Kill: Paul Liao ---- 給笑點、接收到的好笑指數及好笑指數門檻 求豪邁大笑的時間 ---- 子題 1 (30):$k=0$ ---- 對接收到的好笑指數做前綴和 若超過笑點就歸零並記錄時間 ---- [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/B.%20Laughing%20Koying/Koying_sub1.cpp) ---- 子題 2 (70):無額外限制 ---- 一樣做前綴和,但是改為 $\ge k$ 才加 ---- [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/B.%20Laughing%20Koying/Koying.cpp) --- ## C ### [Coding 夢之國的付錢問題 (Coin)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/C) AC: 12 First Kill: Paul Liao ---- 最大可以交易兩倍的價錢 問最少的硬幣交易量 ---- 子題 1 (40):$d_{i-1}\mid d_i$ ---- 使用貪心法 建出 $\le 2p$ 所需的最少硬幣數量表 最後枚舉 Jack 付的價錢 時間複雜度:$O(np)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/C.%20Coin/Koying_sub1.cpp) ---- 子題 2 (60):無額外限制 ---- 經典的硬幣問題 使用 DP 建出 $\le 2p$ 所需的最少硬幣數量表 最後枚舉 Jack 所付的價錢,找到最後的答案 時間複雜度:$O(np)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/C.%20Coin/Koying.cpp) --- ## D ### [Coding 夢之國的過年分配問題 (New Year)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/D) AC: 10 First Kill: Paul Liao ---- 二分圖塗色問題 ---- 子題 1 (13):$n \le 20$, 若可以使每一家都團圓,那麼總統規劃的一定是最佳方案 ---- 若可成功團圓則一定是最佳方案,因此只需要判斷是否為二分圖 並利用邊所連接的兩點是否分配到不同數字來驗證二分圖 時間複雜度:$O(m)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/D.%20New%20Year/Koying_sub13.cpp) ---- 子題2 (27):$n \le 20$ ---- 利用二元枚舉,枚舉每個家庭分配到 $0/1$ 判斷是否為二分圖之後,再跟總統規劃的方案比較 找到最佳的方案 時間複雜度 $O(2^n\times m)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/D.%20New%20Year/Koying_sub12.cpp) ---- 子題 3(18) 若可以使每一家都團圓,那麼總統規劃的一定是最佳方案 ---- 同子題 1 時間複雜度 $O(m)$ ---- 子題 4(42):無額外限制 ---- 在同一個連通塊中,合法的二分途圖色方法只有兩種 因此我們對於每個連通塊都 DFS 一次 若每個連通塊其中一種塗色方法與總統分配的差為 $cnt$ 那麼這個連通塊的最少更改數量就是 $\min(cnt, 點的數量-cnt)$ 將每個連通塊的最少數量相加就是最後的答案 時間複雜度:$O(m)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/D.%20New%20Year/Koying.cpp) --- ## E ### [Koying 的彈跳床飛行記 (Flying Koying)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/E) AC: 6 First Kill: Paul Liao ---- 在 $1$ ~ $n-1$ 中最多選 $k$ 個點,點與點之間最多不能超過 $r$ 求最大總和 ---- 子題 1 (15): $r = n, n \le 500$ ---- 訂狀態 $dp[i][j]$ 為跳了 $i$ 次並落地在 $j$ 的最大快樂指數總和 則 $\displaystyle dp[i][j] = \max_{l < j}(dp[i - 1][l] + h[l])$ 每次轉移 $O(n)$ 時間複雜度 $O(n^2k)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/E.%20Flying%20Koying/Koying_sub1.cpp) ---- 子題 2 (35): $r=n$ ---- 基於子題 1 的 DP 式 我們可以利用前綴 DP 將其優化 將 $dp[i][j]$ 訂為跳了 $i$ 次並落地不遠於 $j$ 的最大快樂指數總和 如此一來,我們的 DP 轉移式就會變成 $dp[i][j] = \max(dp[i][j - 1], dp[i - 1][j - 1] + h[j - 1])$ 時間複雜度 $O(nk)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/E.%20Flying%20Koying/Koying_sub2.cpp) ---- 但實際上 前兩子題只要從 $h[1]$ ~ $h[n - 1]$ 中挑前 $k$ 大的 將其相加就是答案了 時間複雜度 $O(nlogn)$ 不過大家可以用前兩個子題來練習一下自己的 DP ouobbb ---- 子題 3 (11): $n \le 500$ ---- 套用子題 $1$ 的 DP 式 $dp[i][j]$ 為跳了 $i$ 次並落地在 $j$ 的最大快樂指數總和 但是這次的轉移式不是 $\displaystyle dp[i][j] = \max_{l < j}(dp[i - 1][l] + h[l])$ 了 由於 $r$ 的限制,所以我們只能從 $j - r$ ~ $j - 1$ 跳過來 因此轉移式為 $\displaystyle dp[i][j] = \max_{j-r \le l < j}(dp[i - 1][l] + h[l])$ 時間複雜度 $O(n^2k)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/E.%20Flying%20Koying/Koying_sub13.cpp) ---- 子題 4 (39): 無額外限制 ---- 因為 $r$ 有限制,因此不能像子題 2 一樣用前綴 DP 這時候觀察我們的 DP 轉移式 $\displaystyle dp[i][j] = \max_{j-r \le l < j}(dp[i - 1][l] + h[l])$ 看到區間最大值,不知道各位會聯想到什麼 ---- 線段樹? 不,我才不是 Colten ---- 這題的滿分需要用到單調佇列 monotonic queue 來優化 時間複雜度 $O(nk)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/E.%20Flying%20Koying/Koying.cpp) --- ## F ### [Colten 的科學展覽會 (Science Fair)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/F) AC: 5 First Kill: Paul Liao ---- 求最長、長度相同且相似程度 $\ge 90\%$ 的子字串長度 ---- 子題 1 (19): $n = m = 10$ ---- 判斷兩個字串不一樣的字母有幾個 若 $> 1$ 那答案就是 $-1$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/F.%20Science%20Fair/Koying_sub1.cpp) ---- 子題 2 (37): $n, m \le 30$ ---- 枚舉開頭、長度 找出最長的相似程度 $\ge 90\%$ 的子字串 時間複雜度 $O(n^5)$ ---- 子題 4 (44): 無額外限制 ---- 可以發現到 我們在做編輯距離的時候 若我們做到長度 $n$ 那麼在 DP 表格中就含有長度為 $1$ ~ $n$ 的編輯距離了 因此可以把枚舉長度的步驟省略 時間複雜度 $O(n ^ 4)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/F.%20Science%20Fair/Koying.cpp) --- ## G ### [高乘載管制 (High‐occupancy vehicle)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/G) AC: 0 真 防破台 ---- 子題 1 (1): 題目範例 ---- 因為我不會輸出 所以出一個子題讓我練習輸出 ---- 子題 2 (13): $N, M, K \le 5$ ---- 因為我不會 Debug 所以出一個子題讓我 Debug ---- 子題 3 (27): $K = 0$ ---- 因為我不會 Dijkstra 所以出一個子題讓我練習 Dijkstra 時間複雜度:$O(n + mlogn)$ ---- 子題 4 (21): $K = 1$ ---- 因為我不會建虛點 所以出一個子題讓我練習建虛點 時間複雜度:$O(n + mlogn)$ 建虛點空間複雜度:$O(mK^2)$ ---- 子題 5 (25): $K \le 10$ ---- 空間爆炸,我很勇 我用 priority_queue 裝 將使用了幾次折價券合併入 pq 的狀態中 省去建虛點的步驟 時間複雜度:$O(n + 10mlogn)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/G.%20High-occupancy%20vehicle/Koying_sub12345.cpp) ---- 子題 6 (13): 無額外限制 ---- priority_queue 也爆炸,沒關係 早上好 Ten Point Round,現在我有兩個 D Dijkstra 與 Dynamic Programming ---- 做 $k + 1$ 次 Dijkstra 第 $i$ 次代表使用 $i$ 次折價券的情況 每次做完 Dijkstra 之後,枚舉 $t (t > i)$ 將每個邊使用 $t-i$ 次折價券之後的邊權對使用 $t$ 次的狀態鬆弛 時間複雜度:$O(k\times(n + mlogn + mk))$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/G.%20High-occupancy%20vehicle/Koying.cpp) --- ## H ### [Coding 夢之國的大胃王 Jack (Big Stomach Jack)](https://codeforces.com/group/H0qY3QmnOW/contest/376232/problem/H) AC: 2 First Kill: Gino ---- 子題 1 (11): $n, q \le 1000,\ k=0$ ---- 暴力找就可以了 時間複雜度:$O(nq)$ ---- 子題 2(17): $n, q \le 1000$ 暴力搜尋 + 修改 時間複雜度:$O(nq)$ ---- 子題 3 (29) $k = 0$ ---- 利用單調佇列維護每個點最多可以吃到哪裡 時間複雜度:$O(n + q)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/H.%20Big%20Stomach%20Jack/Koying_sub13.cpp) ---- 子題 4 (43): 無額外限制 ---- 使用線段樹維護區間內最小的美味指數以及其位置 利用線段樹上二分搜,得出最多可以吃幾個食物 並利用查詢到的位置做修改 時間複雜度:$O(qloglogn)$ [參考程式](https://github.com/NHDK-Ten-Point-Round/ten-point-round-17/blob/main/solution/H.%20Big%20Stomach%20Jack/Koying.cpp)
{"metaMigratedAt":"2023-06-16T22:31:20.865Z","metaMigratedFrom":"YAML","title":"TPR#17 題解","breaks":false,"slideOptions":"{\"theme\":\"solarized\",\"transition\":\"slide\",\"transitionSpeed\":\"fast\"}","contributors":"[{\"id\":\"73093035-99f8-4a9b-b033-c17f49e2d490\",\"add\":7790,\"del\":382}]"}
    1037 views