题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2631
#include <cstdio>
#include <cstring>
int n;
char str[1010];
// d[i]代表将str[0...i]分组的最小组数
int d[1010];
bool judge(int i, int j);
// flag[i][j]为1代表str[i...j]为回文,为0代表不为回文
int flag[1010][1010];
bool get(int begin, int end);
int main()
{
scanf("%d", &n);
int count = 0;
while(count < n)
{
memset(str, 0, sizeof(str));
memset(flag, -1, sizeof(flag));
scanf("%s", str);
int len = strlen(str);
// 判断回文情况
get(0, len-1);
/*
for(int i = 0; i <= len-1; i++)
{
for(int j = i; j <= len-1; j++)
printf("(%d,%d): %d\n", i, j, flag[i][j]);
}
*/ for(int i = 0; i < len; i++)
{
// if(judge(0, i))
if(flag[0][i])
{
// printf("here\n");
d[i] = 1;
}
else
{
d[i] = i+1;
for(int j = 0; j < i; j++)
{
// if(judge(j+1, i))
if(flag[j+1][i])
{
if(d[i] > d[j]+1)
d[i] = d[j]+1;
}
}
}
// printf("d[%d] = %d\n", i, d[i]);
}
printf("%d\n", d[len-1]);
count++;
}
return 0;
}
/*
// 判断str[i...j]是否为回文串
bool judge(int i, int j)
{
int a;
int end = (i+j-1)/2;
for(int a = i; a <= end; a++)
{
if(str[a] != str[i+j-a])
return false;
}
return true;
}*/
// 判断回文情况
// 判断str[begin...end]是否为回文
bool get(int begin, int end)
{
// printf("here: (%d %d) \n", begin, end);
if(flag[begin][end] != -1)
return flag[begin][end];
if(begin == end)
{
flag[begin][end] = 1;
return flag[begin][end];
}
if(str[begin] == str[end])
{
if(begin == end-1)
flag[begin][end] = 1;
else
flag[begin][end] = get(begin+1,end-1);
}
else
flag[begin][end] = 0;
get(begin, end-1);
get(begin+1, end);
return flag[begin][end];
}
该题动态规划较容易想到。其中注意的是,
给定一个字符串str, 得到str[i...j]是否为回文可以动态规划做。