UVA11584 划分成回文串

时间:2022-05-03 16:42:28

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=105116#problem/B

紫书275

题意:输入一个字符,最少能划分几个回文串

分析:预处理一下,判断i,j是否为回文串;动态分析求解,dp[i] = dp[i - 1] + 1,假设i单独成为一个回文串,然后在往前找,如果j到i是回文,dp[i] = min(dp[i], dp[j - 1] + 1)

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAX = + ;
const int INF = 0x3f3f3f3f;
char s[MAX];
int dp[MAX],len,is_h[MAX][MAX];
void judge_huiwen()
{
int x,y;
memset(is_h, , sizeof(is_h));
for(int i = ; i <= len; i++)
{
x = i - ;
y = i + ;
while(x > && y <= len && s[x] == s[y])
{
is_h[x][y] = ;
x--;
y++;
}
x = i;
y = i + ;
while(x > && y <= len && s[x] == s[y])
{
is_h[x][y] = ;
x--;
y++;
}
}
}
int main()
{
int test;
scanf("%d", &test);
while(test--)
{
scanf("%s", s + );
len = strlen(s + );
memset(dp,,sizeof(dp));
dp[] = ;
judge_huiwen();
for(int i = ; i <= len; i++)
{
dp[i] = dp[i - ] + ;
for(int j = i - ; j > ; j--)
{
if(is_h[j][i])
{
dp[i] = min(dp[i], dp[j - ] + );
}
}
}
printf("%d\n",dp[len]);
}
return ;
}