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;
}

 

posted @ 2013-05-29 13:56  心向往之  阅读(153)  评论(0编辑  收藏  举报