一本通 高手訓練 1781 死亡之樹 狀態壓縮dp

2022-02-04 21:29:26 字數 926 閱讀 3598

link:死亡之樹

關於去重 還是有講究的。

題目求本質不同的 具有k個葉子節點的樹的個數 不能上矩陣樹。

點數很少容易想到裝壓dp 考慮如何刻畫樹的形狀 發現乙個維度做不了 所以。

設狀態 f[i][j]表示 點的集合為i葉子集合的點為j的方案樹。

這樣我們就能知道這棵樹大致的樣子 空間 為\(2^\)

當然 如果使用三進製狀壓 空間複雜度還會進一步降到3^n 不過這道題沒有卡空間。

考慮轉移 可以列舉點 也可以列舉邊。

先考慮列舉邊 會出現重複的情況 如先加這條邊再加那條邊 兩條邊可以交換。

考慮強制按順序的話 需要記上次加入的邊是什麼。時間上過不了。

考慮最後除以(n-1)! 這樣也不行因為 這樣的話 每次考慮加入邊的時候點的狀態的刻畫存在問題。

考慮列舉點 此時實質還是在加邊 還是有重複的。

甚至在某個時刻都有可能出現順序帶來方案數不同的問題。

還是考慮點的有序性 考慮 從乙個狀態到達另外乙個狀態轉移的唯一性。

可以發現在列舉決策的時候 只有當前決策大於葉子節點的最大的那個再進行轉移 此時這樣就保證了每一種樹都是以唯一的方式構造出來的。

證明 倒著想 考慮當前的一棵樹的上乙個狀態 一定是當前狀態減掉最大編號的葉子節點得到的 如果不是 那麼上個狀態是不能轉移到當前狀態的。

歸納一下可以得證。

const ll maxn=11;

ll n,maxx,m,k;

ll sum[1<>1]+(i&1);

rep(1,maxx,i)

}} }

ll ans=0;

for(ll j=maxx;j;j=maxx&(j-1))if(sum[j]==k)ans+=f[maxx][j];

putl(ans);return 0;

}

一本通 高手訓練 遊戲通關

遊戲通關 xy在玩乙個包含n n 個任務的遊戲。每個任務完成時限為t i ti 你可以認為還沒開始做任務時的時間為0 0 獎勵為w i wi 由於xy技術的嫻熟以及任務的簡單,對於每個任務,他都可以在乙個單位時間內完成。xy想要知道他能夠獲得的最多的獎勵。第一行乙個整數n n,表示需要完成的任務數目...

一本通 高手訓練 撲克牌

一副撲克牌有n n張牌。一般你買的一副新撲克牌裡除了這n n張牌外還會有一些張特殊的牌,如果你不小心弄丟了n n張牌中的某一張,就可以用特殊牌來代替,但是如果你弄丟兩張的話就沒有辦法了,因為特殊牌上的圖案是一樣的。現在你得到了很多撲克牌,準確來說,n n n種牌你各有a1,a2,an a1,a2,a...

一本通 Trie字典樹

phone list includeusing namespace std const int n 1e5 5 int t,n,tot,c n 10 char s 10 bool ans,bo n void clear bool insert bo u 1 return flag int main ...