【URAL 1635】Mnemonics and Palindromes(区间DP+记录路径)

来源:互联网 发布:java最新版本 编辑:程序博客网 时间:2024/05/22 06:13

【URAL 1635】Mnemonics and Palindromes(区间DP+记录路径)

题目大意:
长度不超4000的串,分割成尽量少的回文串,并输出。

n^2的预处理出每个区间是否为回文串,区间dp的方式,枚举子串长,枚举子串起点,然后判断即可。

之后就是套路的贪心……ans[i]表示子串[1,i]能分割成的最少回文串的数量。然后记录一下切割点。递归输出。

代码如下:

#include <iostream>#include <cmath>#include <vector>#include <cstdlib>#include <cstdio>#include <climits>#include <ctime>#include <cstring>#include <queue>#include <stack>#include <list>#include <algorithm>#include <map>#include <set>#define LL long long#define Pr pair<int,int>#define fread(ch) freopen(ch,"r",stdin)#define fwrite(ch) freopen(ch,"w",stdout)using namespace std;const int INF = 0x3f3f3f3f;const int msz = 10000;const int mod = 1e9+7;const double eps = 1e-8;const int maxn = 4123;char str[maxn];bool pal[maxn][maxn];int dp[maxn][maxn];int ans[maxn];int pre[maxn];void init(int n){    for(int len = 1; len <= n; ++len)        for(int i = 1,j = i+len-1; j <= n; ++i,++j)            pal[i][j] = (i+1 >= j-1 ||pal[i+1][j-1]) && str[i] == str[j];}bool f = 0;void prt(int n){    if(n == 0) return;    prt(pre[n]);    if(f) putchar(' ');    else f = 1;    char ch = str[n+1];    str[n+1] = 0;    printf("%s",str+pre[n]+1);    str[n+1] = ch;}int main(){    //fread("");    //fwrite("");    int n;    scanf("%s",str+1);    n = strlen(str+1);    init(n);    for(int i = 1; i <= n; ++i)    {        ans[i] = ans[i-1]+1;        pre[i] = i-1;        for(int j = 1; j < i; ++j)        {            if(pal[j][i] && ans[j-1]+1 < ans[i])             {                pre[i] = j-1;                ans[i] = min(ans[i],ans[j-1]+1);            }        }    }    printf("%d\n",ans[n]);    prt(n);    return 0;}
0 0
原创粉丝点击