这道题题解好像都是把所有的循环节都转移了一遍,但是我只转移了最短的循环节也过了,这是为什么?
我的代码:
#include<bits/stdc++.h>
using namespace std;
int dp[101][101],g[101][101];
int len[101][101];
char s[101],*ss=s+1;
const int SIG=1e5;
int _10[101];
string getans(int l,int r){
// cerr<<l<<" "<<r<<"\n";
if(!g[l][r]){
string tmp;
tmp.clear();
for(int i=l;i<=r;i++)tmp+=s[i];
return tmp;
}
if(g[l][r]==SIG){
string tmp;
tmp.clear();
tmp+=to_string((r-l+1)/len[l][r]);
tmp+='(';
tmp+=getans(l,l+len[l][r]-1);
tmp+=')';
return tmp;
}
return getans(l,g[l][r])+getans(g[l][r]+1,r);
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
for(int i=1;i<=9;i++)_10[i]=1;
for(int i=10;i<=100;i++)_10[i]=_10[i/10]+1;
while(cin>>ss){
memset(g,0,sizeof g);
int n=strlen(ss);
for(int i=1;i<=n;i++){
for(int j=i;j<=n;j++){
for(int k=j-i+1;k>=1;k--){
if((j-i+1)%k==0){
bool flag=1;
for(int o=i;o<=j&&flag;o+=(j-i+1)/k){
for(int p=1;p<=(j-i+1)/k;p++){
if(s[o+p-1]!=s[i+p-1]){
flag=0;
break;
}
}
}
if(flag){
len[i][j]=(j-i+1)/k;
break;
}
}
}
}
}
for(int i=1;i<=n;i++)for(int j=i;j<=n;j++)dp[i][j]=j-i+1;
for(int i=2;i<=n;i++){
for(int j=1;j<=n-i+1;j++){
for(int k=j;k<j+i-1;k++){
if(dp[j][j+i-1]>dp[j][k]+dp[k+1][j+i-1]){
g[j][j+i-1]=k;
dp[j][j+i-1]=dp[j][k]+dp[k+1][j+i-1];
}
}
if(dp[j][j+i-1]>_10[i/len[j][j+i-1]]+2+dp[j][j+len[j][j+i-1]-1]){
g[j][j+i-1]=SIG;
dp[j][j+i-1]=_10[i/len[j][j+i-1]]+2+dp[j][j+len[j][j+i-1]-1];
}
}
}
cout<<dp[1][n]<<"\n";
// cout<<getans(1,n)<<"\n";
}
return 0;
}
(从双倍经验改过来的)