首页 > 代码库 > Uva 1630 折叠串

Uva 1630 折叠串

题目链接:https://uva.onlinejudge.org/external/16/1630.pdf

题意:折叠串,给一个字符串,相同部分可以折叠,折叠可以嵌套。求最短长度的一种折叠方法。括号和数字的长度也要考虑进去。

 

刚看到这个题目,没有一点思路,还是大牛们厉害!

 

分析:一个串,可以转成两种形式,要么本身可以转成有重叠部分的串,要么分成两个部分,再转成有重叠部分的串。

本身是否是重叠串,利用kmp查,分成两个部分,遍历一遍所有情况,这样,dp顺序就出来了,最外层是每次查的长度,第二层就是,利用这个长度,从每一个点开始查起。状态描叙是d[i][j]从 i  到 j 的最短字符串。

 

 1 #include <bits/stdc++.h> 2 using namespace std; 3  4 const int maxn = 100 + 10; 5  6 string d[maxn][maxn]; 7 char s[maxn],t[maxn]; 8  9 10 11 int f[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 void getFail(char* s)26 {27     int len = strlen(s);28     f[0] = f[1] = 0;29     for(int i=1; i<len; i++)30     {31         int j = f[i];32         while(j&&s[i]!=s[j])33             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)!=EOF)41     {42         int len = strlen(s);43         for(int i=0; i<len; i++)44             d[i][i] = string("")+s[i];45 46 47         for(int l=2; l<=len; l++)48         {49             for(int i=0; i + l - 1 < len; i++)50             {51                 int j = i + l - 1;52                 d[i][j] = "";53                 for(int k=i; k<=j; k++)54                 {55                     d[i][j] +=s[k];56                     t[k-i] = s[k];57                 }58 59                 t[j-i+1] = 0;60                 getFail(t);61                 if(l%(l-f[l])==0)   //自身是重复的62                 {63                     int cycle = l - f[l];64                     string t = "";65                     t = ToString(l/cycle);66                     t+=(;67                     t+=d[i][i+cycle-1];68                     t+=);69                     if(t.length()<d[i][j].length()) d[i][j] = t;70                 }71 72                 for(int k=i; k<j; k++)73                 {74                     if(d[i][k].length()+d[k+1][j].length()<d[i][j].length())75                     {76                         d[i][j] = d[i][k] + d[k+1][j];77                     }78                 }79             }80         }81         cout<<d[0][len-1]<<endl;82     }83     return 0;84 }

 

Uva 1630 折叠串