UVa 1630 串折叠

https://vjudge.net/problem/UVA-1630

题意:

给出一个由大写字母组成的长度为n的串,折叠成一个尽量短的串。例如:AAAAAAAAABABABCCD折叠成9(A)3(AB)CCD。

 

思路:

参考自http://blog.csdn.net/a197p/article/details/48701227。自己实在是没什么思路,也是看了很久才搞明白。

DP[i][j]表示的是 i~j 压缩后的长度。

fold[i][j]存储 i~j 压缩后的状态。

 1 #include<iostream> 
 2 #include<string>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 
 7 const int INF = 0x3f3f3f3f;
 8 string str;
 9 int DP[110][110];
10 string fold[110][110];
11 
12 int judge(int l, int r)
13 {
14     //这里判重用的就是枚举  
15     for (int i = 1; i <= (r - l + 1) / 2; i++)
16     {
17         if ((r - l + 1) % i) continue;
18         bool flag = true;
19         for (int j = l; j + i <= r; j++)
20         {
21             if (str[j] != str[j + i])
22             {
23                 flag = false;
24                 break;
25             }
26         }
27         if (flag) return i;
28     }
29     return false;
30 }
31 
32 int fun(int l, int r)
33 {
34     if (DP[l][r] != -1) return DP[l][r];
35 
36     if (l == r)
37     {
38         DP[l][r] = 1;
39         fold[l][r] = str[l];
40         return 1;
41     }
42     int k;
43     int re = INF;
44     //找到一个k,两段折叠后连接达到最短
45     for (int i = l; i < r; i++)
46     {
47         int tmp = fun(l, i) + fun(i + 1, r);
48         if (tmp < re) { k = i; re = tmp; }
49     }
50     fold[l][r] = fold[l][k] + fold[k + 1][r];
51     int len = judge(l, r);
52     //对重复串的压缩  
53     if (len)
54     {
55         bool test = true;
56         for (int i = l; i <= r; i++)
57         {
58             if (str[i] == '(' || str[i] == ')') test = false; //不要把括号作为压缩对象  
59         }
60         char t[10];
61         sprintf(t, "%d", (r - l + 1) / len);
62         string newstr = t + string("(") + fold[l][l + len - 1] + string(")");
63         if (test && newstr.size()<re)
64         {
65             re = newstr.size();
66             fold[l][r] = newstr;
67         }
68     }
69     DP[l][r] = re;
70     return re;
71 }
72 
73 int main()
74 {
75     //freopen("D:\\txt.txt", "r", stdin);
76     while (cin >> str)
77     {
78         int R = str.size() - 1;
79         memset(DP, -1, sizeof(DP));
80         fun(0, R);
81         cout << fold[0][R] << endl;
82     }
83     return 0;
84 }

 

posted @ 2017-02-08 16:03  Kayden_Cheung  阅读(199)  评论(0编辑  收藏  举报
//目录