題解【P6289 [COCI2016-2017#1] Vještica】
傳送門。
$\texttt{Description}$
給定 $n$ 個字串,你可以將任意個字串重組,使得儲存這些單詞的 $\text{Trie}$ 數的節點數儘量小。$1\le n\le 16$。
$\texttt{Solution}$
第一眼發現 $n\le 16$,可以考慮狀壓 $\texttt{DP}$。
我們設 $f[s]$ 表示插入完集合 $s$ 中的所有字串的最小節點數。
那麼顯然答案是 $f[S]$,$S$ 表示所有字串的集合。
考慮轉移。
先解決一種簡單的情況,假設說只有兩個字串 $A,B$,那麼將它們插入到 $\text{Trie}$ 樹上後所需的節點數為 $len_A+len_B-\text{same}(A,B)$,$\text{same}(A,B)$ 指 $A$ 和 $B$ 可能的最長公共字首。
這種簡單的情況是可以推廣到 $n$ 個字串的。
對於 $f[s]$,我們考慮列舉 $s$ 的子集 $s'$,那麼 $s\operatorname{xor} s'$ 是 $s$ 的另一個子集 $s''$。
我們直接對於 $s'$ 和 $s''$ 看做兩個字串,長度分別為 $f[s']$ 和 $f[s'']$,所以就可以歸結為兩個字串的情況。
於是得到了最終的狀態轉移方程:$f[s]=\min_{s'\in s}\{f[s']+f[s\operatorname{xor} s']-\operatorname{same}(s)\}$。
考慮函式 $\operatorname{same}$ 如何求。
我們貪心的想,對於一個字元 $c$,我們考慮集合中所有字串中 $c$ 的數量,找到最小的那一個,記為 $x$,是不是說明公共的長度又能減少 $x$,因為所有的字串都有這 $x$ 個字元 $c$。我們對於每一個字元都求一遍相應的 $x$,求和,便是 $\operatorname{same}(s)$ 的值。
細節留給讀者自行處理。
貼一下程式碼:
#include<cstdio> #include<cstring> using namespace std; const int MAXN(18); const int MAXM(1e6+10); const int INF(1e9+10); int n; char s[MAXN][MAXM]; int fac[MAXN],len[MAXN]; inline int lowbit(int x){return x&(-x);} inline int Min(int x,int y){return x<y?x:y;} int pos[MAXN]; int dp[1<<MAXN]; int mp[MAXN][27]; int main() { scanf("%d",&n); for(register int i=1;i<=n;i++) scanf("%s",s[i]+1); fac[0]=1; for(register int i=1;i<=n;i++) fac[i]=fac[i-1]<<1; for(register int i=1;i<=n;i++) { len[i]=strlen(s[i]+1); for(register int j=1;j<=len[i];j++) { int c=s[i][j]-'a'+1; mp[i][c]++; } } for(register int i=1;i<fac[n];i++) { if(i==lowbit(i))//單獨選了一個 { for(register int j=1;j<=n;j++) if(i&fac[j-1]) { dp[i]=len[j]; break; } continue; } int sum=0,tot=0,minlen=INF; for(register int j=1;j<=n;j++) if(i&fac[j-1]) pos[++tot]=j,minlen=Min(minlen,len[j]); //找出i中有哪些字串,將編號記錄到pos中 for(register int c=1;c<=26;c++)//列舉每一個c,找相應的x { int minn=INF; for(register int j=1;j<=tot;j++) minn=Min(minn,mp[pos[j]][c]); sum+=minn;//求 same 的值 } dp[i]=INF; for(register int j=(i-1)&i;j;j=(j-1)&i)//列舉i的子集 dp[i]=Min(dp[i],dp[j]+dp[i^j]-sum); } printf("%d\n",dp[fac[n]-1]+1); return 0; }
$$\texttt{The End.by UF}$$