-
Notifications
You must be signed in to change notification settings - Fork 11
/
SPOJ15558.cc
70 lines (64 loc) · 1.58 KB
/
SPOJ15558.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// SPOJ 15558: Let us play with strings
// http://www.spoj.com/problems/IITKWPCE/
//
// Solution: DP, string (rolling hash)
//
// opt s[0,i) = min { opt [0,j) + 1 : [i,j) is palindrome }
// substring palindromicity can be checked by a rolling hash.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <cstring>
#include <functional>
#include <algorithm>
using namespace std;
#define ALL(c) c.begin(), c.end()
#define FOR(i,c) for(typeof(c.begin())i=c.begin();i!=c.end();++i)
#define REP(i,n) for(int i=0;i<n;++i)
#define fst first
#define snd second
typedef unsigned long long ULL;
struct RollingHash {
static const ULL p = 1000000007ULL;
string s;
int n;
vector<ULL> pow, phash, rhash;
RollingHash(string s) : s(s), n(s.size()),
pow(n+1), phash(n+1), rhash(n+1) {
pow[0] = 1; phash[0] = 0; rhash[n] = 0;
REP(i, n) {
phash[i+1] = s[i] + phash[i] * p;
rhash[n-i-1] = s[n-i-1] + rhash[n-i] * p;
pow[i+1] = pow[i] * p;
}
}
bool isPalindrome(int i, int j) {
ULL a = phash[j] - phash[i] * pow[j-i];
ULL b = rhash[i] - rhash[j] * pow[j-i];
return a == b;
}
};
//
// f s[0,k) = min { 1 + f s[0,i) : [i,k) is parindrome }
int solve(string s) {
int n = s.size();
RollingHash RH(s);
vector<int> c(n+1, n);
c[0] = 0;
for (int k = 1; k <= n; ++k) {
for (int i = 0; i <= k; ++i) {
if (RH.isPalindrome(i, k))
c[k] = min(c[k], 1 + c[i]);
}
}
return c[n];
}
int main() {
int T; scanf("%d", &T);
while (T--) {
char buf[2010];
scanf("%s", buf);
printf("%d\n", solve(buf));
}
}