回文串劃分
阿新 • • 發佈:2017-08-23
方式 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;
}
回文串劃分