传送门
题目大意:可以把给定的字符串进行若干次折叠.即把ABABABAB这种有循环节的字符串折叠成为4(AB).需要注意的是,这个折叠是可以嵌套的,例如下面这个字符串:
ABABABXYZXYZXYZXYZNASANASAABABABXYZXYZXYZXYZNASANASA
第一次折叠后:
2(ABABABXYZXYZXYZXYZNASANASA)
第二次折叠后:
2(3(AB)4(XYZ)2(NASA))
这是这题的唯一坑点.
我的思路很暴力,每次检测[l,r]看是否能够折叠.这个过程用一次kmp就可以解决.最小循环节存在的条件:字符串的长度设为n 若next[n] && n%(n-next[n]) == 0.循环节长度==n-next[n].网上有不少关于这方面的讲解.就不进行证明了.
代码
#pragma GCC optimize(2)
#define LL long long
#define pq priority_queue
#define ULL unsigned long long
#define pb push_back
#define mem(a,x) memset(a,x,sizeof a)
#define pii pair<int,int>
#define fir(i,a,b) for(int i=a;i<=(int)b;++i)
#define afir(i,a,b) for(int i=(int)a;i>=b;--i)
#define ft first
#define vi vector<int>
#define sd second
#define ALL(a) a.begin(),a.end()
#define bug puts("-------")
#define mpr(a,b) make_pair(a,b)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
const int INF = 0x3f3f3f3f;
inline void read(int &a){
int x = 0,f=1;char ch = getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){
x=x*10+ch-'0';ch=getchar();}
a = x*f;
}
int n,dp[110][110],nxt[110];
string dps[110][110];
void getnxt(string s){
int n = s.size(),i=2,j=0;
s = ' ' + s;
mem(nxt,0);
for(;i<=n;++i){
while(j && s[i] != s[j+1]) j = nxt[j];
if(s[i] == s[j+1]) j++;
nxt[i] = j;
}
}
string s;
string dfs(int l,int r){
string str = "";
if(dp[l][r] != INF) return dps[l][r];
if(l == r){
dp[l][r] = 1;
str += s[l];
return dps[l][r] = str;
}
int res = 0;
string tmp="";
fir(i,l,r) tmp += s[i];
int siz = tmp.size();
getnxt(tmp);
int replen = siz-nxt[siz];
if(nxt[siz] && siz % replen == 0){
res = 2;
int len = siz/(replen);
while(len){
res++;
str += char((len%10)+'0');
len/=10;
}
reverse(ALL(str));
str += '(';
str += dfs(l,l+replen-1);
res += dp[l][l+replen-1];
str += ')';
}
else res = INF;
fir(i,0,r-l-1){
string s1 = dfs(l,l+i),s2 = dfs(l+i+1,r);
if(res > dp[l][l+i]+dp[l+i+1][r]){
str = s1+s2;
}
res = min(res,dp[l][l+i]+dp[l+i+1][r]);
}
dp[l][r] = res;
return dps[l][r] = str;
}
int main(){
cin >> s;
n = s.size();
s = ' ' + s;
mem(dp,INF);
cout << dfs(1,n);
return 0;
}