UVa 1630 区间DP Folding

一个字符串如果能简写,要么是重复多次,按题中的要求简写;要么是左右两个部分分别简写后再拼起来。

dp(i, j)表示字串(i, j)所能被简写的最短的字符串。

 

判断一个字符串是否为周期串以及求出它的周期用的KMP算法。

 

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <string>
 6 using namespace std;
 7 
 8 const int maxn = 100 + 10;
 9 
10 char s[maxn], t[maxn];
11 string d[maxn][maxn];
12 
13 string ToString(int x)
14 {
15     string ans = "";
16     while(x)
17     {
18         ans += (char) ('0' + (x % 10));
19         x /= 10;
20     }
21     reverse(ans.begin(), ans.end());
22     return ans;
23 }
24 
25 int f[maxn];
26 void getFail(char* s)
27 {
28     int len = strlen(s);
29     f[0] = f[1] = 0;
30     for(int i = 1; i < len; i++)
31     {
32         int j = f[i];
33         while(j && s[i] != s[j]) j = f[j];
34         f[i+1] = s[i] == s[j] ? j+1 : 0;
35     }
36 }
37 
38 int main()
39 {
40     while(scanf("%s", s) == 1)
41     {
42         int len = strlen(s);
43         for(int i = 0; i < len; i++) d[i][i] = string("") + s[i];
44 
45         for(int l = 2; l <= len; l++)
46         {
47             for(int i = 0; i + l - 1 < len; i++)
48             {
49                 int j = i + l - 1;
50                 d[i][j] = "";
51                 for(int k = i; k <= j; k++) { d[i][j] += s[k]; t[k-i] = s[k]; }
52 
53                 t[j - i + 1] = 0;
54                 getFail(t);
55                 if(l % (l - f[l]) == 0)
56                 {
57                     int cycle = l - f[l];
58                     string t = "";
59                     t = ToString(l / cycle);
60                     t += '(';
61                     t += d[i][i + cycle - 1];
62                     t += ')';
63 
64                     if(t.length() < d[i][j].length()) d[i][j] = t;
65                 }
66 
67                 for(int k = i; k < j; k++)
68                 {
69                     if(d[i][k].length() + d[k+1][j].length() < d[i][j].length())
70                         d[i][j] = d[i][k] + d[k+1][j];
71                 }
72             }
73         }
74 
75         cout << d[0][len - 1] << endl;
76     }
77 
78     return 0;
79 }
代码君

 

posted @ 2015-09-04 16:02  AOQNRMGYXLMV  阅读(244)  评论(0编辑  收藏  举报