【HDOJ】2144 Evolution
并查集+DP。
1 /* 2144 */ 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 6 #define MAXN 105 7 8 char s[MAXN][MAXN]; 9 int dp[MAXN][MAXN]; 10 int lens[MAXN]; 11 int pre[MAXN]; 12 13 int find(int x) { 14 if (pre[x] == x) 15 return x; 16 pre[x] = find(pre[x]); 17 return pre[x]; 18 } 19 20 void merge(int x, int y) { 21 int xx = find(x); 22 int yy = find(y); 23 24 if (xx != yy) { 25 pre[xx] = yy; 26 } 27 } 28 29 int cal(int x, int y) { 30 int i, j, k, tmp; 31 int ret; 32 33 for (j=0; j<=lens[y]; ++j) 34 dp[0][j] = 0; 35 for (i=0; i<=lens[x]; ++i) 36 dp[i][0] = 0; 37 ret = -1; 38 for (i=1; i<=lens[x]; ++i) { 39 for (j=1; j<=lens[y]; ++j) { 40 if (s[x][i] == s[y][j]) 41 dp[i][j] = dp[i-1][j-1] + 1; 42 else 43 dp[i][j] = 0; 44 if (dp[i][j] > ret) 45 ret = dp[i][j]; 46 } 47 } 48 49 return ret; 50 } 51 52 int main() { 53 int n, t = 0; 54 int i, j, k, tmp; 55 int x, y; 56 int ans; 57 double p; 58 59 #ifndef ONLINE_JUDGE 60 freopen("data.in", "r", stdin); 61 #endif 62 63 while (scanf("%d %lf", &n, &p) != EOF) { 64 for (i=1; i<=n; ++i) { 65 scanf("%s", s[i]+1); 66 pre[i] = i; 67 lens[i] = strlen(s[i]+1); 68 } 69 for (i=1; i<=n; ++i) { 70 for (j=1; j<i; ++j) { 71 x = find(i); 72 y = find(j); 73 if (x != y) { 74 k = cal(i, j); 75 if (k*100.0/lens[i]>p && k*100.0/lens[j]>p) { 76 pre[y] = x; 77 } 78 } 79 } 80 } 81 ans = 0; 82 for (i=1; i<=n; ++i) 83 if (pre[i] == i) 84 ++ans; 85 86 printf("Case %d:\n%d\n", ++t, ans); 87 } 88 89 return 0; 90 }