题意:
给你一个字符串,要你最少划分几次,把它都变成回文串,起初没什么思路,但是数据不大,可以暴力dp。
复杂度:1000x1000x500
思路:
for(i; i<=len; i++)
for(dp[i]=1005, j=1; j<=i; j++)
- 定义dp【i】为第i个位置时的最小划分。
- 每次都考察第i个位置前的最小划分。
- 假如 j–i 是回文,那么就dp【i】=min(dp【i】,dp【j-1】+1)
更新dp【i】为本次划分的回文 j—i,和j之前划分的回文dp【j-1】
考察j之前的最小划分dp【j-1】,加上这次的划分1。
#include <iostream>
#include <cstring>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
using namespace std;
const int maxn=1e3+10;
char s[maxn];
int dp[maxn];
bool judge(int i, int j)
{
while(i<=j)
{
if(s[i]!=s[j])return 0;
i++,j--;
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n;
cin>>n;
while(n--)
{
cin>>s+1;
int len=strlen(s+1);
dp[0]=0;
int j;
For(i,1,len)
{
for(dp[i]=1005,j=1;j<=i; j++)
{
if(judge(j,i))
{
dp[i]=min(dp[i],dp[j-1]+1);
}
}
}
cout<<dp[len]<<endl;
}
return 0;
}