Ural 1238 Folding 题解
题意
定义折叠、展开为:
- 单个大写英文字母是一个折叠的串,把它展开后是它本身。
- 如果$S$和$Q$是折叠的串,则$SQ$也是折叠的串。如果$S$展开后为$S’$,$Q$展开后为$Q’$,则$SQ$展开后为$S’Q’$。
- 如果$S$是个折叠的串,则$X(S)$也是折叠的串,其中$X$是一个十进制大于$1$的整数,如果$S$展开为$S’$,则$X(S)$展开后为$S’$重复$X$次。
给定一个字符串(长度小于等于$100$),求把它折叠后有最小长度的那个字符串。
题解
考虑记忆化搜索(DP也可以)。
定义$f(s)$为$s$字符串折叠后有最小长度的那个字符串。
边界为当$|s|\le4$($|s|$为$s$的长度)时,$f(s)=s$。
给定$s$,求出$f(s)$有以下几种方式
$f(s)=s$。
设$1<x\le|s|,|s|\%x=0$且有字符串$q$,$q$重复$x$次为$s$,$f(s)=x“(”+f(q)+“)”$。
设$0<i<|s|$,$f(s)=f(s[0..i-1])+f(s[i..|s|-1])$。
取长度最小的值即可,不要忘了记忆化。
程序
1 | // #pragma GCC optimize(2) |