# BZOJ1093 [SCOI2003]字符串折叠

## Sample Input

NEERCYESYESYESNEERCYESYESYES

14

## 题解

$$f_{i,i+1}=1$$

$$f_{i,j}=min\left(min\{f_{i,k} +f_{k,j}\mid i < k < j\}, min\{f_{i,k} + 2 + num((j - i) / (k - i)) \mid i < k < j, S_{i,j} = \frac{j-i}{k-i}S_{i,k}\}\right)$$

$$\sum_{d|len}(len-d)$$

\begin{aligned} \sum_{l=1}^n(n-l+1)\sum_{d|l}(l-d) &\leq \sum_{l=1}^nn\sum_{d|l}l\\ &= n\sum_{l=1}^nl\sum_{d|l}1\\ &= n\sum_{d=1}^n\sum_{d|l, 1 \leq l \leq n}l\\ &= n\sum_{d=1}^nd\sum_{l'=1}^{\lfloor\frac{n}d\rfloor}l'\\ &= n\sum_{d=1}^nd\frac{\lfloor\frac{n}d\rfloor\left(\lfloor\frac{n}d\rfloor+1\right)}2\\ &\leq n\sum_{d=1}^n\frac{n\left(\frac{n}d+1\right)}2\\ &\backsim \frac{n^3}2\sum_{d=1}^n\frac{1}d\\ &=O(n^3logn)\end{aligned}

#include <algorithm>
#include <cstdio>
#include <cstring>
using std::min;
char s[105];
inline bool eq(int b1, int b2, int len) {
return !strncmp(s + b1, s + b2, len);
}
inline int wei(int x) {
int t = 1;
while (x /= 10) ++t;
return t;
}
int f[105][105];
int main() {
scanf("%s", s);
int n = strlen(s);
for (int len = 1; len <= n; ++len)
for (int i = 0; i + len <= n; ++i) {
int j = i + len;
f[i][j] = len;
for (int k = i + 1; k < j; ++k) {
f[i][j] = min(f[i][j], f[i][k] + f[k][j]);
if (!(len % (k - i)) && eq(i, k, j - k))
f[i][j] = min(f[i][j], f[i][k] + 2 + wei(len / (k - i)));
}
}
printf("%d\n", f[0][n]);
return 0;
}


posted @ 2017-06-12 15:31  _rqy  阅读(...)  评论(...编辑  收藏