uva 11584 动态规划
题意:給一个字符串,把它分成许多子串,要求每个子串必须是回文串,问最少分成几个子串?
分析:dp[i]表示1~i分成的最少子串数,dp[i] = min (dp[j-1] + 1),(j~i是回文).
const int M = 1005; char s[M]; int len; int c[M];//c[i]表示以1~i的最少回文个数 int pre[2][M], p, q, x, y;//pre[][i]到i是一个回文,即pre[][i]是i所在回文的对称点 //p q是滚动数组下标 x y是个数 int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int T; scanf("%d", &T); s[0] = '#'; c[0] = 0; while(T--){ scanf("%s", s+1); len = strlen(s+1); x = p = 0; FOE(i, 1, len){ y = 0; q = 1-p; pre[q][y++] = i; c[i] = c[i-1]+1;//本身是长度为1的回文 if(s[i]==s[i-1]) {//和前一个相同,长度为2的回文 pre[q][y++] = i-1; checkmin(c[i], c[i-2]+1); } FOR(j, 0, x){//i-1到pre[p][j]是回文 int t = pre[p][j]-1; if(s[t] == s[i]){//i和pre[p][j]-1相同,则i到pre[p][j]-1是回文 checkmin(c[i], c[t-1]+1); pre[q][y++] = t;//记录回文的另一端点 } } p = q; x = y; } printf("%d\n", c[len]); } return 0; }