PCCA Winter Camp Day1 === ##### 2021.02.01 ##### tags: `PCCA` `NCTU` `NYCU` ##### link: https://vjudge.net/contest/420760#overview 題解 === ## RPG Protagonist > 兩人分別可帶重量不多於$p$、$f$的物品, > 現有$cnt_{a}$件$A$物品,每件重$w_{a}$, > $cnt_{b}$件$B$物品,每件重$w_{b}$, > 求能帶走物品總數(無論種類)的最大值。 $p$、$f$、$w_{a}$、$w_{b}$數據範圍皆到$1e9$,因此能判斷多半不是背包問題。 觀察可發現$cnt_{a}$、$cnt_{b}$數據範圍僅到$2e5$,是可以枚舉的範圍。 枚舉第一個人拿幾個$A$物品($[0, \frac{p}{w_{a}}]$),剩餘空間貪心拿盡量多的$B$物品,而第二個人則先拿剩餘物品中較輕的物品,拿完再拿較重的物品。 ## Perfect party > 有$m$個物品,每件有重量$w_{i}$跟價值$v_{i}$兩個屬性, > 且有$k$組關係,說明$X$物品跟$Y$物品在同一個集合中。 > 現可帶走重量不多於$n$的物品, > 但要求每個集合至少要帶走一個物品, > 求可獲取價值的最大值。 > 若無解,則輸出"trash problem"。 先用並查集判別物品集合,再做背包取物品。 分組背包:(至少選一個) - $dp[i][j]$表示,前$i$組物品,重量上限為$j$時的最大獲利。 - 初始化:($-1$代表無解) - $dp[0][j] = 0$, $j \in [0, n]$ - $dp[i][j] = -1$, $i \in [1, group]$, $j \in [0, n]$($group$為組別數量) - 轉移: - 要決定$dp[i][j]$,為確保此組別有選,轉移一定要選擇物品,不能直接從$dp[i - 1][j]$轉移,也不能從無解的轉移。 - $dp[i][j] = max(dp[i][j], dp[i - 1][j - w[k]] + v[k], dp[i][j - w[k]] + v[k])$,$j \geq w[k]$ - 遍歷順序: ```cpp for (int i = 1; i <= 組別數量; i++) for (int k = 0; k < 組內物品數量; k++) for (int j = n; j > -1; j--) 轉移; ``` - $dp[group][n]$即為答案。 ## Perfect walker > 給一個樹形圖, > 從任意點出發遍歷, > 求最短路徑。 對一樹形圖,從任意點出發遍歷再回到原點的路徑長為兩倍的路徑和。 因題目不用回到原點,故考慮省下最長距離為樹形圖中最遠點距離。 最短路徑 = 2 * 路徑和 - 樹的直徑 ## Perfect student > 給一個$n$個點、$m$個邊的有向圖, > 若點$A$被標記, > 則點$A$指向的點也被標記, > 求選擇標的最少幾個點, > 可使所有點都被標記。 由題意可知,一個強聯通分量中任意點被標記,等價於全部點被標記,因此可用kosaraju或tarjan將一個強聯通分量縮為一點。 縮點後可得一有向無環圖,入度為0的點一定會被選擇,不然該點不可能被標記,反之入度不為0的點,一定會透過其他點被標記,因此入度為0的點數即為答案。 ## Intervals > 給定$n$個區間, > 每個區間$[a_{i}, b_{i}]$上至少有$c_{i}$個不重複的點屬於集合$s$, > 要滿足所有條件, > 求問$s$中最少點數。 令$d[i]$,為前$i$個點選擇的點數,則條件轉化為差分約束的形式: 1. $d[b_{i}] - d[a_{i} - 1] \geq c_{i}$ 2. $d[i] - d[i-1] \geq 0$ 3. $d[i-1] - d[i] \geq -1$ 由於為$\geq$,故差分約束建圖後做最長路即為解。 ## Radar Installation > 給$n$個點和雷達距離$d$, > 之後給$n$個點的$x$跟$y$, > 雷達站都要建在$X$軸, > 輸出總共需要幾個雷達站才能完全覆蓋所有點, > 如果無法覆蓋則輸出$-1$。 可以先判如果有點的$y$座標絕對值$\geq d$的話就無法完全覆蓋。 算出每個點的覆蓋區間,對所有點的區間左界做排序,之後由左到右做Greedy。 Greedy的方法:(令$cur$為現在建雷達站的座標) 1. 如果此點的左區間$\leq cur$,則$cur$取此點的右區間和$cur$的最小值。 2. 如果此點的左區間$> cur$,表示要新建一個雷達站,且建立在此點的右區間。 ## Stacking Boxes > 有$n$個$m$維度的箱子, > 要找出最多層的巢狀箱子, > 裡面的箱子每個維度的邊長都要小於外面的箱子的邊長。 > 輸出最多幾層以及由內而外的順序。 先把每個箱子的維度做排序,如果$A$箱可以放進$B$箱的話,表示重新排序後,$B$的每個維度都要大於$A$。 可以利用 $O(n^2m)$ 方法建圖,如果$A$可以放進$B$,則建立一條邊由$A$指向$B$,最後再從入度為$0$的點開始移除,並記錄連結,即可得最長路徑。 ## Walk Through the Forest > 有$n$個點、$m$條邊的有權無相圖, > 從$V_1$出發走到$V_2$有條件地走,有幾種走法。 > 條件為如果要從$A$點走到$B$點, > 則必須存在一條$B$走回$V_2$的路徑比$A$走回$V_2$的所有路徑都短。 這題先求出所有點到$V_2$的最短路,由於圖無向,也就是$V_2$到所有點的最短路。然後再建立新的圖如果$A$到$V_2$的最短路大於$B$到$V_2$的最短路,則建立一條有向邊$A$到$B$。之後再用$dfs$來計算總共有幾種走法。 ## Knight Moves > 給兩個西洋棋上的座標, > 看騎士從一個點到另外一個點最少需要幾步。 騎士可以走$(2, 1) (2, -1) (-2, 1) (-2, -1) (1, 2) (1, -2) (-1, 2) (-1, -2)$,用$queue$做$bfs$即可得到答案。 ## Collectors Problem > 有$N$個人(含Bob)和$M$種貼紙, > 每個人手上都有不同種類及張數的貼紙, > Bob要和別人交換使他有最多種類的貼紙。 > 交換規則:Bob給其他人的貼紙是其他人沒有的,其他人給Bob的貼紙是其他人多餘的(至少$2$張),且其他人只與Bob交換。 把題目轉成網路圖: 1. 源點(Bob) &rarr; 每種貼紙:容量為Bob所擁有的貼紙數。 2. 每種貼紙 &rarr; 其他人:如果那個人沒有此貼紙的話容量為$1$,否則為$0$。 3. 其他人 &rarr; 每種貼紙:如果那個人貼紙的數量$\geq 2$,則容量為此人所擁有的此貼紙數$-1$,否則為$0$。 4. 每種貼紙 &rarr; 匯點:容量為$1$。 找出圖的最大流就是答案了。 ## Lucky array > 維護一個array, > 如果數字裡沒有$4$跟$7$以外的數字就是幸運數字, > $count\ a\ b$:要找$a$到第$b$個數有幾個幸運數字。 > $add\ a\ b\ c$:要把第$a$到第$b$個數都加上$c$ 用$fenwick\ tree$紀錄每個數字是否為$lucky\ number$,是為$1$、不是為$0$。 區間修改時用$O(n)$的方法修改。 經hank55663指正: 幸運數總共有$30$個,每次用線段樹作區間加值,然後紀錄每個數離下一個幸運數的距離,若超過的話直接更改,因此每個數最多被硬改$30$次。 複雜度:$O((30n+q)logn)$。 用線段樹的方法請參考原題解:https://codeforces.com/blog/entry/2956