題解 Vjestica (狀壓DP)

2021-10-10 01:21:00 字數 983 閱讀 4023

有n個字元合集,求其字首樹的最少結點個數。

資料範圍

n ≤ 16,1 ≤ m ≤1000000(字元個數)

首先看到

n ≤ 16

可知,這道題是狀壓dp或者暴力

狀態是什麼?

因為是n的資料範圍小,n為字元合集個數,所以狀態是 n個字元合集的整體 的選擇情況,

這裡用s表示,二進位制範圍為 1~1111111111111111。

怎麼進行轉移?

因為目標值是字首樹的最少結點個數,

所以可以把這棵樹拆為兩顆進行合併,這也是樹形dp的常見思路。

怎麼拆?

因為這顆字首樹在節點數最少的條件下,一種結構就可能由不同狀態轉移而來,

所以,須列舉所有選擇情況。

怎麼合?

因為我們列舉了所有選擇情況,其中一定有可轉移為最優結構的選擇,

所以我們直接把兩棵樹都連上根,把字首樹的公共字首合併,

即 減去現在所有選擇的字元合集的交集的字元個數。

#include

using

namespace std;

int n,_[16]

[26],cnt[17]

[26],dp[

1<<16]

;char a[16]

[1000006];

intlcp

(int s)

for(

int k=

0;k<

26;k++

)len+

=_[n]

[k];

return len;

}int

dfs(

int s)

intmain()

}printf

("%d"

,dfs((

1<)+1)

;}

狀壓dp題解

實現 includeconst int maxn 1 20 1 typedef long long ll ll f maxn a 25 a x 記錄第x行的障礙狀態 int lowbit int x int main f 0 1 乙個也不放也是一種方案 int maxs 1 判斷當前狀態下狀態的1的...

題解 星空 狀壓DP

這道題思維難度非常高,有很多處理的小技巧,並且 也有很多細節 這道題是一種序列的區間操作,我們都知道,區間操作比較麻煩,所以我們要想辦法將區間操作轉換成單點修改 這時,我們想到了差分,假如我們對乙個序列進行操作,這時乙個序列裡的相對狀態不會變只有兩端改變,換句話說就是這個序列的差分並不會發生改變,只...

狀壓dp 撲街題解

基礎知識位運算 1.與 x y表示x和y在二進位制下滿足,每一位有0則0,否則為1的標準進行按位與 2.或 x y表示在二進位制下每一位按照全0則0,否則為1的標準按位或 3.異或 x y 同為假,異為真 4.判斷乙個十進位制數x在二進位制下第i為是否為1 if 1 i 1 x 0 5.將乙個x進製...