题目大意
一个小写字母组成的字符串,将它们划分为若干个回文串,谁求最少能划分为多少个回文子串
分析
首先就是打表,用一个mark数组表示 mark(i,j)表示i-j是否是一个回文子串
然后用递推公式递推
我们用d(i)表示从1-i的字符串可以划分为最少多少个回文串 ,
初始化为:
d(i)=d(i-1)+1
状态转移方程为:
d(i)=min{d(j-1)+1|i<j,mark(j,i)是一个回文串}
代码如下
#include<iostream>
#include<algorithm>
#include<string.h>
#include<string>
#define maxn 1000+10
using namespace std;
int vis[maxn][maxn],mark[maxn][maxn],d[maxn];
char ch[maxn];
void dp(int i, int j)
{
if (j < i) return ;
if (vis[i][j]) return ;
vis[i][j] = 1;
int &ans = mark[i][j];
if (i == j) ans = 1;
else if(ch[i]==ch[j]&&j - i == 1) ans = 1;
else if (j - i == 1) ans = 0;
dp(i + 1, j);
dp(i, j - 1);
if (ch[i] == ch[j] && mark[i + 1][j - 1] == 1)ans=1;
}
int main()
{
int t;
cin >> t;
while (t--)
{
int flag = 0;
cin >> ch+1;
memset(vis, 0, sizeof(vis));
memset(mark, 0, sizeof(mark));
int len = strlen(ch+1);
dp(1, len);
d[0] = 0;
for (int i = 1; i <= len; i++) {
d[i] = d[i - 1] + 1;
for (int j = 1; j <= i; j++) {
if (mark[j][i])
d[i] = min(d[i], d[j - 1] + 1);
}
}
cout << d[len] << endl;
}
return 0;
}