CQOI2017 老C的鍵盤

2022-05-02 03:33:08 字數 825 閱讀 1079

一句話題意:給你一棵完全二叉樹,每條邊有乙個方向,求這棵樹有多少種不同的拓撲序。

簡化題意後,其實就是乙個普及組樹形 dp。

設 \(dp(i,j)\) 表示以點 \(i\) 為根的子樹中,\(i\) 號點排第 \(j\) 名的方案數。

利用 \(j\) 這個輔助維,我們可以列舉點 \(i\) 的排名 \(k\),掃一遍點 \(i\) 的所有兒子,每次會新來乙個以 \(v\) 為根的子樹合併到以 \(i\) 為根的子樹上,列舉點 \(i\) 和點 \(v\) 在各自子樹中的排名(記為 \(rank_i\) 和 \(rank_v\)),若題目限制點 \(i\) 排在點 \(v\) 前面,則列舉要滿足 \(rank_i+rank_v\le k\),否則題目限制點 \(i\) 排在點 \(v\) 後面,則列舉要滿足 \(rank_i+rank_v\gt k\)。

設從 \([1,k-1]\) 中選 \(rank_i-1\) 個整數的方案數為 \(l\),從 \([k+1,size_i+size_v]\) 中選 \(size_i-rank_i\) 個整數的方案數為 \(r\),則 \(dp(i,k) += dp(i,rank_i)\times dp(v,rank_v)\times l\times r\)。這很好理解。

最後算時間複雜度,還是那個套路,看起來是 \(o(n^4)\),其實還是 \(o(n^3)\),因為最裡面兩層迴圈的最大上界分別為 \(size_i\) 和 \(size_v\),這等價於在兩棵子樹內選 \(2\) 個點。那麼這就是個以前講過的套路,樹上每對點只會在 lca 處被列舉一次,故最裡面兩層迴圈套 dfs 的時間是 \(o(n^2)\),乘上乙個列舉 \(k\) 的迴圈,總時間 \(o(n^3)\)。

code

CQOI2017 老C的鍵盤

發現題目給的很像一棵樹。就把這棵樹建出來。發現如果把大於小於號分別看成一條有向邊,發現這個題目就是求這個圖有多少個拓撲序。對於每乙個拓撲序,直接 12345 這樣標號就可以得到滿足題目要求的序列。考慮樹 dp 設 f i,j 為 i 這個點在這個子樹所形成的拓撲序列中在第 j 位的方案數。轉移的時候...

題解 CQOI2017老C的鍵盤

建議大家還是不要閱讀此文了,因為我覺得這題我的解法實在是又不高效又不優美 只是想要記錄一下,畢竟是除了中國象棋之外自己做出的組合dp第一題 首先如果做題做得多,比較熟練的話,應該能一眼看出這題所給的資訊正好描述的是一棵二叉樹上父子的大小關係。於是確立乙個狀態 f u i 表示在 u 及 u 的子樹內...

CQOI2017 老C的方塊

傳送門 nkoj4042 這是一道網路流題。我在這道題上耗了很久 感謝 oblack幫我修改 這道題的思維上的難度並不大。以下是我的想法 首先要確定乙個大的方向,題目中要求移除一些方塊使得剩餘方塊無法構成 討厭的形狀 很容易就想到了最小割。仔細觀察一下,可以發現這些討厭的形狀是由兩個方格 一條特殊的...