题意:将一串字符串划分成尽量少的回文串。
思路: 首先枚举回文串起始字符,标记所有回文串。dp[i]为0~i的最小划分回文串。dp[i]=dp[i-1]+1,dp[i]=min(dp[j-1]+1) j~i为回文串。
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <string>
#include <cmath>
#include <vector>
#include <utility>
#include <set>
#include <climits>
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define INF 2147483647
using namespace std;
typedef long long ll;
int n,i,j;
string s;
bool ok[1005][1005];
int dp[1005];
int main()
{
scanf("%d",&n);
while(n--)
{
cin>>s;
memset(ok,false,sizeof(ok));
memset(dp,0,sizeof(dp));
for(i=0; i<s.size(); i++)
{
for(j=s.size(); j>=i; j--)
{
int l=i,r=j;//l,r为枚举回文串起始坐标
while(s[l]==s[r])
{
l++;
r--;
}
if(l>r)
{
if(i!=j)
ok[i][j]=true;
}
}
}
// for(i=0;i<s.size();i++)
// for(j=i;j<s.size();j++)
// if(ok[i][j])
// cout<<i<<" "<<j<<endl;
dp[0]=1;
for(i=0; i<s.size(); i++)
{
if(i>0)
dp[i]=dp[i-1]+1;
for(j=0; j<i; j++)
{
if(ok[j][i])
{
dp[i]=min(dp[i],dp[j-1]+1);
// cout<<i<<" "<<dp[i]<<endl;
}
}
}
printf("%d\n",dp[s.size()-1]);
}
return 0;
}