Trie
首先题目的名字都告诉你了这题是一道关于字典树的题目(我一开始就没用这个。。。所以GG了30分
为什么要用trie树呢?
Trie 的强大之处就在于它的时间复杂度。它的插入和查询时间复杂度都为 O(k) ,其中 k 为 key 的长度,与 Trie 中保存了多少个元素无关。Hash 表号称是 O(1) 的,但在计算 hash 的时候就肯定会是 O(k) ,而且还有碰撞之类的问题;Trie 的缺点是空间消耗很高。不过这道题的空间是绝对足够的
把他打乱得全排列用vector记录下来然后在用trie树去判断就行了
#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
int n,f[65540],cnt[17][27];
char c[1000001];
int calc (int s)
{
int x[27];
memset(x,127,sizeof(x));
for (int i=1; i<=n; i++)
if (s&(1<<i-1))
for (int j=1; j<=26; j++)
x[j]=min(x[j],cnt[i][j]);
int ans=0;
for (int i=1; i<=26; i++)
ans+=x[i];
return ans;
}
int dfs (int s)
{
if (~f[s])
return f[s];
int num=calc(s);
if (lowbit(s)==s)
return f[s]=num;
int ans=2147483647;
for (int i=(s-1)&s; i; i=(i-1)&s)
ans=min(ans,dfs(i)+dfs(s^i)-num);
return f[s]=ans;
}
int main()
{
scanf("%d",&n);
for (int i=1; i<=n; i++)
{
scanf("%s",c+1);
for (int j=1; j<=strlen(c+1); j++)
cnt[i][c[j]-96]++;
}
memset(f,255,sizeof(f));
printf("%d\n",dfs((1<<n)-1)+1);
return 0;
}