UVa 11488 超级前缀集合(Trie的应用)

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\n",ans);
61     }
62     return 0;
63 }

 

posted @ 2017-11-25 10:27  Kayden_Cheung  阅读(293)  评论(0编辑  收藏  举报
//目录