1044 - Palindrome Partitioning(记忆化DP)

来源:互联网 发布:淘宝 进口啤酒真相 编辑:程序博客网 时间:2024/05/24 04:06

A palindrome partition is the partitioning of a string such that each separate substring is a palindrome.

For example, the string “ABACABA” could be partitioned in several different ways, such as {“A”,”B”,”A”,”C”,”A”,”B”,”A”}, {“A”,”BACAB”,”A”}, {“ABA”,”C”,”ABA”}, or {“ABACABA”}, among others.

You are given a string s. Return the minimum possible number of substrings in a palindrome partition of s.

Input
Input starts with an integer T (≤ 40), denoting the number of test cases.

Each case begins with a non-empty string s of uppercase letters with length no more than 1000.

Output
For each case of input you have to print the case number and the desired result.

Sample Input
Output for Sample Input
3
AAAA
ABCDEFGH
QWERTYTREWQWERT
Case 1: 1
Case 2: 8
Case 3: 5

把一个字符串分割成几个部分,要求每个部分都是回文串,问最少分成几个部分。

先处理出哪些区间是回文区间,然后进行记忆化搜索(搜索的时候要注意,只找满足l,i区间是回文的i进行记忆化,否则超时,至于这个剪枝,原因也很简单,因为不是回文也没有搜索的必要了),具体看代码。

#include<cstdio>#include<cstring>#include<iostream>#include<queue>#include<vector>#include<algorithm>#include<string>#include<cmath>#include<set>#include<map>#include<vector>#include<stack>#include<utility>#include<sstream>using namespace std;typedef long long ll;const int inf = 0x3f3f3f3f;const int maxn = 1005;int t;char s[1005];int dp[1005][1005];bool leap[1005][1005];int dfs(int l,int r){    if(dp[l][r] != -1)return dp[l][r];    if(leap[l][r])return dp[l][r] = 1;    int ans = r - l + 1;    for(int i = l;i < r;i++)    {        if(leap[l][i])            ans = min(ans,1 + dfs(i + 1,r));    }    return dp[l][r] = ans;}int main(){    #ifdef LOCAL    freopen("C:\\Users\\巍巍\\Desktop\\in.txt","r",stdin);    //freopen("C:\\Users\\巍巍\\Desktop\\out.txt","w",stdout);    #endif // LOCAL    int kase = 1;    scanf("%d",&t);    while(t--)    {        scanf("%s",s);        memset(leap,false,sizeof(leap));        int len = strlen(s);        for(int i = 0;i < len;i++)        {            leap[i][i] = true;            for(int j = 1;i >= j && i + j < len;j++)            {                if(s[i - j] == s[i + j])                    leap[i - j][i + j] = true;                else                    break;            }        }        for(int i = 0;i < len - 1;i++)        {            if(s[i] == s[i + 1])            {                leap[i][i + 1] = true;                for(int j = 1;i >= j && i + 1 + j < len;j++)                {                    if(s[i - j] == s[i + 1 + j])                        leap[i - j][i + 1 + j] = true;                    else                        break;                }            }        }        memset(dp,-1,sizeof(dp));        printf("Case %d: %d\n",kase++,dfs(0,len - 1));    }    return 0;}
0 0
原创粉丝点击