https://vjudge.net/problem/UVA-11488
题意:
给定一个字符串集合S,定义P(s)为所有字符串的公共前缀长度与S中字符串个数的乘积。比如P( {000, 001, 0011} ) = 6。给n个01串,从中选择一个集合S,使得P(S)最大。
思路:
建立字典树,边插入边统计答案即可。
用两个变量分别记录前缀数量和前缀长度,每次插入时动态更新两者乘积。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 const int maxn = 50000*200+5; 6 7 int num; 8 int ans; 9 10 struct Trie 11 { 12 int son[2]; 13 int cnt; 14 int id; 15 }t[maxn]; 16 17 void init(int x) 18 { 19 t[x].cnt = t[x].id = 0; 20 memset(t[x].son,0,sizeof(t[x].son)); 21 } 22 23 void insert(char* s) 24 { 25 int u = 0, n = strlen(s); 26 for(int i=0;i<n;i++) 27 { 28 int c = s[i]-'0'; 29 if(!t[u].son[c]) 30 { 31 num++; 32 init(num); 33 t[u].son[c] = num; 34 } 35 int pre = u; 36 u = t[u].son[c]; 37 t[u].id = t[pre].id+1; 38 t[u].cnt++; 39 ans = max(t[u].cnt*t[u].id, ans); 40 } 41 } 42 43 char s[205]; 44 45 int main() 46 { 47 //freopen("in.txt","r",stdin); 48 int T; 49 scanf("%d",&T); 50 while(T--) 51 { 52 num = ans = 0; 53 init(0); 54 int n; scanf("%d",&n); 55 while(n--) 56 { 57 scanf("%s",s); 58 insert(s); 59 } 60 printf("%d ",ans); 61 } 62 return 0; 63 }