1. 程式人生 > >回文串劃分

回文串劃分

方式 main scanf sample ont sca tput 例如 include

題目:

有一個字符串S,求S最少可以被劃分為多少個回文串。 例如:abbaabaa,有多種劃分方式。 a|bb|aabaa - 3 個回文串 a|bb|a|aba|a - 5 個回文串 a|b|b|a|a|b|a|a - 8 個回文串 其中第1種劃分方式的劃分數量最少。

Input

輸入字符串S(S的長度<= 5000)。

Output

輸出最少的劃分數量。

Sample Input

abbaabaa

Sample Output

3

分析:
題目意思還是很好懂的,不像比賽的幾個題目我連題意都沒看懂,但是看懂了題目也不代表我就能AC。
dp[i]是字符1~i劃分成的最小回文串的個數,則有dp[i]=min{dp[i],dp[j]+1 | a[j+1~i]是回文串}

可以先用O(n²)的時間判斷s[i...j]是否為回文串。

AC代碼:
#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<algorithm>
#include<cmath>
char a[5005];
int dp[5005];
using namespace std;
int deal(int w,int v)   //判斷是否為回文串
{
    int mid=v-(v-w)/2;  //
取中點 for (int i=w,j=v;i<=mid;i++,j--) if(a[i]!=a[j]) return 0; return 1; } int main() { scanf("%s",a+1); int len=strlen(a+1); for (int i=1;i<=len;i++) { dp[i]=dp[i-1]+1; for (int j=0;j<i;j++) { if (deal(j+1
,i)&&dp[i]>dp[j]+1) dp[i]=dp[j]+1; } } cout << dp[len] << endl; return 0; }

 

回文串劃分