UVa:11584 Partitioning by Palindromes

犯了一个SB错误。

假如说读 str+1 ,那么str+1的最后一个字符的下标应该是strlen(str+1),\0是第strlen(str+1)+1。这点和读str不一样,不要搞错了。

一开始想了个类似是区间dp的思路,对于给定区间分别枚举截点求它们的和,三重循环结果超时了。

后来想出来了这个代码,我今天脑袋有点晕乎乎的,也说不清楚它的正确性。。

dp[j][i]表示区间ji之间的最少回文串数,对于每个终点i枚举起点j,如果起点和终点的字符相同而且它们之间的最少回文串数是1,那么ji之间的最少回文串数也是1.否则ji之间的最少回文串数就是dp[j][i-1]+1.然后同时枚举断点求和比较得最小的dp[1][i],最后的答案就是dp[1][L].

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1005
#define INF 2139062143
using namespace std;
char str[MAXN];
int L,dp[MAXN][MAXN];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",str+1);
        L=strlen(str+1);
        memset(dp,0x7f,sizeof(dp));
        for(int i=0; i<=L; ++i) dp[i][i]=1;
        for(int i=1; i<=L; ++i)
        {
            for(int j=i-1; j>=1; --j)
            {
                if(i==j||(str[j]==str[i]&&(j+1==i||dp[j+1][i-1]==1)))
                    dp[j][i]=1;
                else dp[j][i]=min(dp[j][i],dp[j][i-1]+1);
                dp[1][i]=min(dp[1][j]+dp[j+1][i],dp[1][i]);
            }
        }
        printf("%d\n",dp[1][L]);
    }
    return 0;
}



 

你可能感兴趣的:(动态规划)