有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進製...