#include #include "optimization.h" #include #include #include using namespace std; char s[101], g[101]; int lcp[101][101] = {}; int ans[101][101] = {}; pair p[101][101]; int get_lcp(size_t i, size_t j) { if(lcp[i][j] == -1) { if(s[i] == 0 || s[j] == 0 || s[i] != s[j]) { lcp[i][j] = 0; } else { lcp[i][j] = get_lcp(i+1, j+1) + 1; } } return lcp[i][j]; } void fill_lcp(size_t n) { for (auto &row : lcp) { for (int &item : row) { item = -1; } } for (int i = 0; i <= n; ++i) { for(size_t j = 0; j <= n; j++) { get_lcp(i, j); } } } bool relax(int& a, int v) { if(a > v) { a = v; return true; } return false; } int length(int k) { if(k == 0) return 1; int ret = 0; while(k > 0) { ret++; k /= 10; } return ret; } int get_ans(int i, int len) { if(ans[i][len] == -1) { ans[i][len] = len; p[i][len] = {-1, 0}; for(int m = 1; m < len; m++) { if(relax(ans[i][len], get_ans(i, m) + get_ans(i+m, len-m))) { p[i][len] = {0, m}; } if (len % m == 0 && lcp[i][i + m] >= len - m) { if(relax(ans[i][len], length(len / m) + get_ans(i, m) + 2)) { p[i][len] = {1, m}; } } } } return ans[i][len]; } void restore(int i, int len, int o) { auto [type, m] = p[i][len]; if(type == -1) { for(int j = 0; j < len; j++) { g[o+j] = s[i+j]; } } else if(type == 0) { int a = get_ans(i, m); restore(i, m, o); restore(i+m, len-m, o+a); } else if(type == 1) { int count = len / m; int clen = length(count); for(int k = clen - 1; k >= 0; k--) { g[o + k] = (char) ('0' + (count % 10)); count /= 10; } g[o+clen] = '('; restore(i, m, o+clen+1); g[o+clen+1+get_ans(i, m)] = ')'; } else { assert(false); } } int main() { readWord(s); size_t n = strlen(s); fill_lcp(n); for (auto &row : ans) { for(auto &item : row) { item = -1; } } get_ans(0, n); restore(0, n, 0); writeWord(g); return 0; }