51NOD 1154 回文串的划分(DP)

思路:参考了网上,思路很清奇,借助vis[i][j]来表示从i到j是否为回文串,回文串这边是用的双重循环来写的;dp[i]用来表示以i结尾的字符串最少的回文串有多长。

#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 5e3 + 10;
int dp[maxn];//dp[i]表示的是以第i个字符结尾的最少划分数
//dp[i] = min(dp[i],dp[j]+1) 当j到i是回文串时
char s[maxn];
bool vis[maxn][maxn];//vis[i][j]表示i到j的字符串是否是回文串
int main(){
    
    gets(s);
    int len = strlen(s);
    memset(vis, 0, sizeof vis);

    for (int i = 0; i < len; i++)
        vis[i][i] = 1;
    
    dp[0] = 1;
    for (int i = 1; i < len; i++){
        dp[i] = i;
        dp[i] = min(dp[i], dp[i - 1] + 1);

        for (int j = i - 1; j >= 0; j--){
            if (j == i - 1 && s[i] == s[j]){
                if (j - 1 >= 0)dp[i] = min(dp[i], dp[j - 1] + 1);
                else dp[i] = 1;
                vis[j][i] = 1;
            }
            else if (vis[j + 1][i - 1] && s[i] == s[j]){
                if (j - 1 >= 0)dp[i] = min(dp[i], dp[j - 1] + 1);
                else dp[i] = 1;
                vis[j][i] = 1;
            }
        }
    }
    cout << dp[len - 1] << endl;
    return 0;
}

 

posted @ 2018-08-21 11:06  我只有一件白T恤  阅读(191)  评论(0编辑  收藏  举报