poj 2176 folding

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 }
View Code
原文地址:https://www.cnblogs.com/Rorshach/p/9275851.html