Description:
就是把一个字符串压尽可能的压缩
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 const int N = 110, INF = 1e9; 6 struct node{ 7 char s[N]; //dp[i][j]的len表示区间i-j压缩后的最小长度 s表示压缩后的字串 8 int len; 9 }dp[N][N]; 10 int n; 11 char s[N]; 12 int main(){ 13 scanf("%s", s + 1); 14 n = strlen(s + 1); 15 for(int i = 1; i <= n; i++) 16 dp[i][i].len = 1, dp[i][i].s[0] = s[i]; 17 for(int l = 2; l <= n; l++) 18 for(int i = 1; i + l - 1 <= n; i++){ //枚举区间 19 int j = i + l - 1; 20 dp[i][j].len = INF; 21 for(int nowl = 1; nowl <= l / 2; nowl++){ //枚举一个区间所有可能被压缩后子串的长度 22 if(l % nowl != 0) continue; //如果无法整除肯定不能被压缩 23 int st = i, ed = i + nowl; 24 while(s[st] == s[ed] && ed <= j) st++, ed++; //检验该串能否被压缩 25 if(ed > j){ 26 int num = l / nowl; //压缩后串的数目为num 27 sprintf(dp[i][j].s, "%d", num); //那么该状态下最小串的开头就是num 28 strcat(dp[i][j].s, "("); 29 strcat(dp[i][j].s, dp[i][i + nowl - 1].s); //把压缩后的串接起来 30 strcat(dp[i][j].s, ")"); 31 dp[i][j].len = strlen(dp[i][j].s); 32 break; 33 } 34 } 35 for(int k = i; k < j; k++) 36 if(dp[i][j].len > dp[i][k].len + dp[k + 1][j].len){ //重新扫一遍区间更新dp[i][j] 37 dp[i][j].len = dp[i][k].len + dp[k + 1][j].len; 38 strcpy(dp[i][j].s, dp[i][k].s); 39 strcat(dp[i][j].s, dp[k + 1][j].s); 40 } 41 } 42 puts(dp[1][n].s); 43 return 0; 44 }