【线性结构上的动态规划】UVa 11584

回文串问题。给出一个字符串,问最少可以划分为多少个字符串子串。

对于判断是否为回文串,对于不是很长的字符串,可以采取直接暴力,即从两边向中间收缩判断字符相等。

1 bool is_pali(int l, int r)
2 {
3     while(l < r)
4     {
5         if(str[l] != str[r]) return false;
6         ++l; --r;
7     }
8     return true;
9 }

本题为简化复杂度,可以先预处理str[j...i]是否为回文串。

设dp[i]表示以第i个字符结尾的子串最少可以划分的回文串数。

则dp[i] = min{dp[i], dp[j-1]+1}; (j <= i && str[j...i]是回文串);

代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
char str[1005];
int dp[1005];
bool is_pali(int l, int r)
{
    while(l < r)
    {
        if(str[l] != str[r]) return false;
        ++l; --r;
    }
    return true;
}
int main()
{
    int T; scanf("%d", &T);
    while(T--)
    {
        scanf("%s", str+1);
        int l = strlen(str+1);
        memset(dp, 0, sizeof(dp)); //dp[i]:以i结尾的串最少可以划分的回文串数
        for(int i = 1; i <= l; i++)
        {
            dp[i] = i; //最多可以划分为i+1个
            for(int j = 1; j <= i; j++)
            {
                if(is_pali(j, i))
                    dp[i] = min(dp[i], dp[j-1]+1); //此处避免下标越界
            }
        }
        cout << dp[l] << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/LLGemini/p/4312457.html