NOI2020 簡要題解

2022-05-04 23:09:10 字數 3092 閱讀 7887

\(a\)

首先不難發現乙個暴力動態規劃的做法 , 記\(f_\)表示第\(i\)天 ,當前在第\(j\)座城市所獲得的最大收益

有轉移方程 \(f_ = max\,u_}+cost_i+extra_\}\)

發現\(w_\)非常小 , 考慮拆點。 將每個點拆成\(w_\)個點 , 那麼一共會有至多\(5n\)個點。

接著 , 考慮矩陣乘法 , 事實上 , 將求和運算改為\(max\)運算 , 並將括號內的改為加法 , 是依然成立的 (廣義矩陣乘法)

那麼我們就只需要預處理\(64\)個矩陣 , 並用向量乘矩陣合併答案

時間複雜度 : \(o()\)

** :

\(b\)

首先對於\(m <= 23\) , 有乙個容斥原理的做法 :

考慮欽定每個限制是否一定不滿足 , 那麼就只需建出虛樹 , 設一共有\(i\)個限制一定不滿足 , 虛樹的長度總和為\(l\) , 對答案的貢獻即為 \((-1)^i \cdot 2^\)

但是這樣的指數級演算法是不能接受的。

考慮乙個動態規劃的思路 :

記 \(f_\) 表示以 \(i\) 為根的子樹 , 在\(j\)深度或更大的點一定要有一條向上邊權為\(1\)的邊的方案數。

轉移的時候只需列舉其兒子節點 , 並討論邊權為\(0/1\)的情況 , 依次合併即可。

直接這樣做是 \(o(nd)\) 的 , 其中\(d\)表示深度

考慮優化 , 不妨寫出轉移方程 : \(dp'_ = dp_ \cdot (sum_ + sum_) + dp_ \cdot sum_\) , 其中\(sum\)表示\(dp\)陣列的字首和。

考慮線段樹合併 , 每次先將左子樹的和累加 , 然後加到右子樹上 , 我們只需對於線段樹上每個節點維護乙個整體乘法標記即可。2023年北大冬令營有過乙個類似的套路。

時間複雜度 : \(o(nlogn)\)

** :

\(c\)

分塊。\(d\)

首先觀察資料範圍 , 有 \(m \geq n - 2\) 。並且部分分中有一檔是 \(m = n - 1\) , 很可能起到提示標準演算法的作用。

考慮\(m = n - 1\)怎麼做。

令 \(d_1 \leq d_2 \leq d_3 .... \leq d_\)

首先 , \(m = n - 1\) 時一定有解。

我們發現 , \(n=2 , 3\) 的情況都可以直接構造 , 那麼我們是否能將 \(n\) 的情況向 \(n - 1\) 轉化呢?

引理 \(1\) : \(d_1 < k\)

證明 : 假設 \(d_1 \geq k\) , 那麼 \(d_1 + d_2 + d_3 + ... + d_n \geq nk > (n - 1)k = d_1 + d_2 + .... + d_n\) , 矛盾。

引理 \(2\) : \(d_ + d \geq k\)

假設 \(d_ + d_n \leq k - 1\) , 那麼 , \(d_n <= k - 1 - d_1\) , 則\(d_1 + d_2 + ... + d_n \leq d_1 + (k - 1 - d_1)(n - 1)\) , 矛盾。

根據這兩條引理 , 我們就獲得了乙個構造方案 , 每次將 \(d_1\) 用完 , 然後用 \(d_n\) 填補空缺 , 當只剩兩個的時候直接放一起即可。

對於 \(m >= n\) 的情況 , 考慮向 \(m = n - 1\)轉化。

引理 \(3\) : \(d_ \geq k\)。

證明 : 若 \(d_ < k\) , 則 \(d_1 + d_2 + ... + d_n < nk \leq mk = d_1 + d_2 + ..... + d_n\)

單獨用一次 \(d_n\) , 就使 \(m\) 減小了\(1\) , 因此可以最終轉化為 \(m = n - 1\)的情況。

綜上 , 我們得到了乙個 \(m \geq n - 1\)時的做法 , 可以得到 \(20\) 分。 如果加上 \(n <= 10\)的暴力做法 , 就可以得到 \(45\) 分的可觀得分。

接著 , 我們考慮如何處理 \(m = n - 2\)。

引理 \(4\) : 問題有解當且僅當可以找到乙個子集 \(s\) , 記 \(x = |s|\) , \(s\)中的元素的和 \(= (x - 1)k\)。

證明 :

充分性 : 顯然 , 對於集合 \(s\) 與集合 \(t = u - s\) , 都是兩個滿足 \(m = n - 1\) 的子問題。 直接對於兩個集合分別構造一組解即可。

必要性 : 考慮一張圖\(g\) , 我們將兩種一起使用的節點連一條邊 , 那麼就一共有 \(n - 2\) 條邊 , 這張圖一定是不連通的。 所以滿足有解一定要找到這樣的乙個集合。

根據引理 \(4\) , 我們可以將每個 \(d_i\) 減去 \(k\) , 那麼就只需判斷是否有乙個集合的元素和為 \(-k\)。

這是乙個經典的揹包問題 , 可以通過 \(bitset\) 優化。

時間複雜度 : \(o()\) , 取 \(w\) = \(32\) 或 \(64\)。

** :

\(e\)

首先引出"好樹"的概念 , 我們將一棵每個節點左右兒子 \(size\) 值的最小值均不超過 \(1\) 的二叉樹稱為好樹。

觀察 \(1\) : 如果僅有有限個好樹不在集合 \(grow(t)\) 中 , 則該集合是幾乎完備的。

觀察 \(2\) : 輸入的集合中 , 非好樹是無用的。

觀察 \(1\) 比較顯然 , 而觀察 \(2\) 是因為根據觀察 \(1\) , 只有好樹是值得關心的。

那麼我們就有了乙個遞迴求解的思路 :

令 \(solve(t)\) 表示樹林 \(t\) 是否幾乎完備。

首先 , 如果有葉子節點 , 返回完備。 如果樹林為空 , 返回不完備。

否則 , 將其分為 \(4\) 類 :

\(1\) : 根只有左兒子。

\(2\) : 根只有右兒子。

\(3\) : 根有左右兒子且左兒子大小為 \(1\)。

\(4\) : 根有左右兒子且右兒子大小為 \(1\)。

判斷這四個子問題是否都成立即可。

因為每個節點的貢獻都是 \(1\) , 因此時間複雜度是 \(o(n)\) 級別。

** :

\(f\)

弦圖。

NOI2020 製作菜品 題解

題意分析 給出 n 個數和 m 個 k 可以某些 k 拆兩個正整數,使得拆後的數可以拼成給出的 n 個數。思路分析 上面的解釋是因為這樣寫比較方便,實際上按照題意應該是用 n 個數拆分拼成 m 個 k 觀察資料範圍,發現有 m geq n 2 的限制和 m geq n 1 的部分分,考慮從這裡切入分...

NOI2020 美食家 題解

題意分析 給出乙個帶權有向圖,要求從節點 1 出發,經過恰好 t 的邊權和,回到節點 1 求可經過的最大點權和。特別地,經過的邊權和達到部分特殊數時,會有某個點的點權發生改變。思路分析 樸素演算法 設 f 表示在節點 j 經過的邊權和為 i 時可經過的最大點權和。很容易可以得出 dp 方程 f ma...

NOI 2020 部分題目題解

這個資料範圍,就是告訴我們這道題要矩陣快速冪。先考慮 k 0 k 0k 0。把每個點拆成五個點,那麼邊權都為 1 11,然後是乙個 floyd 求最長路。轉移是廣義的矩陣乘法,滿足結合律,可以套上矩陣快速冪。k 0 k neq 0 k 0 我考場的做法比較暴力,直接把美食節的時間排序,分段暴力求。時...