上午三個多小時考四道題的 DP。
賽時會的分:[100](?) + 100 + [30](?) + 100。
估分:100 + 100 + 0 + 100。
實際分:10 + 100 + 0 + 100。
掛巨量的分,掛了 120 分。
下面是一些值得注意的點:
T1
就是分組揹包。DP 陣列下標要考慮負數可以直接全體加一個值變成非負的,[或者用 map 之類的](?)(& 不知道 unordered_map 會不會被卡)。
我賽時的做法是每個掛鉤的位置加上 15 變成非負的,然後最後要看質量之和 * 15 的地方的 DP 值。感覺可能是對的,不知道為啥掛了。
T2
數位 DP 的基礎題,做法比較板。
注意 0 算不算貢獻;注意是 < x 還是 <= x;注意 dig 陣列不是輸入的字串(代表數),而是那個字串的 1 ~ ... 位翻轉後的結果(就是要注意是從低位到高位存的還是從高位到低位存的)。
對於要不要用高精度,可能可以先寫一份用 long long 之類的的程式碼,然後拿它跑極限資料看會不會爆 long long。但是這樣會不會爆成負數又加回正數從而導致判斷失誤啊?
T3
感覺是非常巧妙的揹包題。
資料範圍較小,想:
- 狀壓
- 搜尋
- 高維 DP
此題即高維 DP。
有序列舉顏色來填以滿足第一種限制(同一行的兩個相鄰點,左點的顏色 <= 右點的顏色)。此處我從小到大列舉顏色。
設 \(f _ { i, a, b, c, d }\) 表示當前填了第 \(0\) 到 \(i\) 個顏色,\(4\) 行分別填到第 \(1\) 位到第 \(a, b, c, d\) 位的方案數。
現在考慮第二種限制怎麼滿足。假設要求 \(a\) 處理的行上的第 \(x\) 位和 \(b\) 處理的行上的第 \(y\) 位顏色相同。那麼填某一種顏色後,要麼 \(a < x\) 且 \(b < y\),要麼 \(a \geq x\) 且 \(b \geq y\)。那麼可以預處理出哪些狀態是不能要的,每一種顏色填完後就把這些狀態的方案數賦為 0。
那麼現在考慮怎麼轉移。考慮一位一位轉移,外層迴圈列舉顏色,內層列舉轉移哪一行的哪一位,像完全揹包那樣轉移。[本質是高維費用的完全揹包,每一個物品是在某一行往右多填一位,費用是 1。](?)於是可以把 \(i\) 那一維去掉。
[std](?)的程式碼寫得很好看。可以參考。我補的程式碼也是這種寫法。
啟發:這種多個並列的東西(如本題中的 \(4\) 行),可以考慮高維 DP,每個開一維。
T4
題解好像是狀壓 DP,用矩陣快速冪來最佳化。[感覺和我的本質上應該差不多。](?)
我的做法:
兩行為一個狀態,把狀態作為點,根據合法轉移在狀態之間連邊,用鄰接矩陣記錄,跑鄰接矩陣的快速冪再統計答案即可。不管不合法的狀態來節省時空。
啟發:這種狀態轉移求路徑數的 DP 可以轉換成圖論題用鄰接矩陣快速冪做。
2024.8.30