1. 程式人生 > 其它 >【改題】Public Round1A 刪數

【改題】Public Round1A 刪數

題目傳送門

題目

給定一個長為 \(n\) 的正整數序列 \(a_1,⋯,a_n\)

你可以進行若干次操作,每次操作你可以選擇一個位置 \(i∈[2,n−1]\) 使得 \(a_i= \frac{a_{i−1}+a_{i+1} }{2}\),隨後將 \(a_i\) 刪去,之後的數按順序向前補空位。

求若干次操作後序列長度最小可以是多少。

題解

現在我已經可以想到差分了,把陣列差分後,問題轉化為每次合併兩個相鄰相同的數為它們之和,那就有一些性質:每次合併後這個數相當於變成原來的兩倍,所以一個數只會和它的\(2\)的冪次倍合併,一個數被合併的次數為\(log\) 次。

我沒做出來的原因是因為忘記了一個“決策”的概念,而一味的在想如何線段樹dp,線段樹dp的問題在於,我只記錄上一個塊的大小, 但是這個塊和上一個合併之後還能繼續往前合併, 這個東西不好記錄也不好轉移,導致我的思路完全錯了。

實際上呢,最終合併出來的序列,每個塊都是由一段連續的塊合併出來的,我們把要合併出這個塊,看作那一段塊中最後一個的決策,這樣就可以進行轉移了,同時一個塊至多合併\(log\)次, 所以只有\(log\)種不同的決策,複雜度也是正確的。

具體來講我們設\(f_i\)表示前 \(i\) 個數合併出的最小塊數, 轉移次列舉第\(i\)個塊被合併了多少次即可。

然後這裡還要一個很妙的dp, 記 \(g_{i, j}\) 表示第\(i\)個塊往左合併\(j\)次需要的左端點, 轉移一下即可。

學到了