1. 程式人生 > >UVa 11488 超級前綴集合(Trie的應用)

UVa 11488 超級前綴集合(Trie的應用)

for uva 定義 ref .so 數量 字典 bsp cst

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 }

UVa 11488 超級前綴集合(Trie的應用)