The main topic: give a string, without changing the contents of the string can be folded, specifically see in the title. Ask how long the shortest string can be folded into.
Idea: Data range is only 100, how violent how to engage. The first is an interval DP, set F[I][J] for the string from I start to j the shortest can be folded into how short. To use the fold in the body of the method, in fact, only need to force enumeration of the paragraph folded into a few paragraphs, and then a hash to determine the line.
Of course, don't forget the normal interval DP.
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 110# Define BASE 23333#define INF 0x3f3f3f3fusing namespace std; Char s[max];unsigned long Long hash[max],power[max];int table[max];int F[max][max]; void Pretreatment () {for (int i = 1; I <= 9; ++i) table[i] = 1; for (int i = ten; I <=; ++i) table[i] = 2; TABLE[100] = 3; Power[0] = 1; for (int i = 1; i < MAX; ++i) power[i] = power[i-1] * BASE;} Inline unsigned long long gethash (int l,int r) {return Hash[r]-HASH[L-1] * power[r-l + 1];} inline int Divide (int L,int R,int p) {if ((r-l + 1)% p) return INF; int len = (r-l + 1)/p; unsigned long long base = Gethash (L,l + len-1); for (int i = l; I <= r; i + = len) if (Gethash (i,i + len-1)! = base) return INF; return Table[p] + 2 + f[l][l + len-1];} int main () {pretreatment (); scanf ("%s", S + 1); int length = strlen (s + 1); for (int i = 1; I <= Length ++i) Hash[i] = hash[i-1] * BASE + s[i]; for (int i = 1, i <= length; ++i) for (int j = i; j <= length; ++j) F[i][j] = j-i + 1; for (int j = 1, j <= length; ++j) for (int i = 1, i + j-1 <= length; ++i) {for (int k = 1; k <= J ++K) F[i][i + j-1] = min (f[i][i + j-1],divide (i,i + j-1,k)); for (int k = 1; k < J; ++k) F[i][i + j-1] = min (f[i][i + j-1],f[i][i + k-1] + f[i + k][i + j-1]); } cout << f[1][length] << Endl; return 0;}
Bzoj 1090 Scoi 2003 string folding interval DP