狀態DP,以dp[i]表示刪減爲狀態i時所需要的最小次數,dp[i] = min(dp[i],dp[j]+1);其中保證j-i是迴文,因爲要保證j狀態包含i狀態,所以第二重循環式j = (j+1)|i。
#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <cmath>
#include <stack>
#include <queue>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef __int64 int64;
typedef long long ll;
#define M 100005
#define max_inf 0x7f7f7f7f
#define min_inf 0x80808080
#define mod 1000000007
int dp[1<<20] , is[1<<20] , len;
char str[20];
bool Judge(int k)
{
int i , cnt = 0;
char temp[20];
for (i = 0 ; i < len ; i++)
{
if (k&1)
temp[cnt++] = str[i];
k >>= 1;
}
for (i = 0 ; i < cnt ; i++)
{
if (temp[i] != temp[cnt-1-i])return 0;
}
return 1;
}
int main()
{
int t , i , j;
scanf("%d",&t);
while (t--)
{
scanf("%s",str);
len = strlen(str);
int up = 1<<len;
memset(is , 0 , sizeof is);
for (i = 1 ; i < up ; i++)
{
if (Judge(i))is[i] = 1;
}
memset(dp , max_inf , sizeof dp);
dp[up-1] = 0;
for (i = up-1 ; i >= 0 ; i--)
{
for (j = i+1 ; j < up ; j = j+1|i)
{
if (is[j-i])
dp[i] = min(dp[i],dp[j]+1);
}
}
printf("%d\n",dp[0]);
}
return 0;
}