Uva 11584 dp分割最少回文串

传送门:https://vjudge.net/problem/UVA-11584

给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串。问最少可以分割成多少个。

f[i]表示以i结尾的串最少可以分割的串数。

f[i] = min{ f[j]+1, 串[j,i]是回文串&&1<=j<=i }

处理好边界,我这里直接以字符串0开始,初始化每个dp[i]最大 = i+1,假定都不能分割。当从0开始到当前i是回文串,则直接赋值1,此时dp[j-1]是不存在的。

遍历以i结尾的所有后缀串,若从j开始到i是回文串,则=min(dp[i],dp[j-1]+1),以此来转移状态,压缩确定最少分割数。

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int INF = 0x3f3f3f3f;
const int MAXN = 1010;

char str[MAXN];
int f[MAXN];

bool isPalind(int l, int r){
    while(l<r){
        if(str[l] != str[r]) return false;
        ++l; --r;
    }
    return true;
}

int main(){

//    freopen("in.txt","r",stdin);
    int T;
    scanf("%d", &T);
    while(T--){

        scanf("%s", str);

        int len = strlen(str);
        memset(f, 1, sizeof(f));
        for(int i = 1; i < len; i++){
            f[i] = i+1;
            for(int j=0; j<=i; j++)
                //遍历以i结尾的每个串
                //如果是回文串,则以j为开头到i的串+1跟当前比较
                if(isPalind(j, i)){
                    if(j==0) {
                        f[i] = min(f[i], 1);
                    }
                    else {
                        f[i] = min(f[i], f[j-1]+1);
                    }
            }
        }
        printf("%d\n", f[len-1]);
    }
    return 0;
}

 

posted @ 2017-07-21 11:45  Lawliet__zmz  阅读(237)  评论(0编辑  收藏  举报