URAL 1635. Mnemonics and Palindromes(简单区间dp)

来源:互联网 发布:快乐十分装机软件 编辑:程序博客网 时间:2024/05/01 16:46

竟然把4000看成了400,当成区间dp做的。O(n)^3的复杂度,托托的超时啊、、、后来看了崔老师写的可以降维,改成二维的就OK了啊。dp[i]表示到第i个是最少有多少个回文。dp[i] = min(dp[i], dp[j] + 1);1表示j+1到i是回文串。需要预处理。

1635. Mnemonics and Palindromes

Time limit: 1.0 second
Memory limit: 64 MB
The student Vasechkin was terribly unlucky at his oral examination. Of 42 examination questions, he didn't prepare only the last one, and he was asked exactly that question. Vasechkin was sitting in front of the professor and couldn't say anything. But the professor was in good mood and gave Vasechkin one last chance to pass the exam. He asked the poor student to name the subject in which the exam was being held. Unfortunately, Vasechkin couldn't recall the name, though he remembered that in that name there were such words as safety, programs, devices, and, possibly, informatics…
To get ready for the reexamination, Vasechkin decided to learn the name of the subject. To better remember that long string, he decided to decompose it into palindromes and learn each of the palindromes separately. Of course, the number of palindromes in the decomposition had to be as small as possible.

Input

In the first line there is the name of the subject in which Vasechkin was examined. This is a nonempty line consisting of lowercase English letters. The length of the line is at most 4000 symbols.

Output

In the first line output the minimal number of palindromes to which the name of the subject can be decomposed. In the second line output palindromes from the optimal decomposition separated by a space. If several answers are possible, output any of them.

Samples

inputoutput
pasoib
6p a s o i b
zzzqxx
3zzz q xx
wasitacatisaw
1wasitacatisaw
#include <algorithm>#include <iostream>#include <stdlib.h>#include <string.h>#include <iomanip>#include <stdio.h>#include <string>#include <queue>#include <cmath>#include <stack>#include <map>#include <set>#define eps 1e-8#define M 1000100#define LL __int64///#define LL long long#define INF 0x3f3f3ff#define PI 3.1415926535898#define MOD 1000000009const int maxn = 4005;using namespace std;char str[maxn];bool vis[maxn][maxn];int dp[maxn];int pre[maxn];int flag[maxn];int n;void Handle(){    for(int i = 0; i < n; i++)    {        for(int j = 1; ; j++)        {            if(i-j < 0) break;            if(i+j >= n) break;            if(str[i-j] != str[i+j]) break;            vis[i-j][i+j] = true;        }        for(int j = 1; ; j++)        {            if(i-j+1 < 0) break;            if(i+j >= n) break;            if(str[i-j+1] != str[i+j]) break;            vis[i-j+1][i+j] = true;        }    }}int main(){    while(cin >>str)    {        n = strlen(str);        memset(vis, false, sizeof(false));        memset(pre, -1, sizeof(pre));        memset(flag, 0 , sizeof(flag));        Handle();        for(int i = 0; i <= n; i++)            dp[i] = INF;        for(int i = 0; i < n; i++)            vis[i][i] = 1;        dp[0] = 1;        for(int i = 0; i < n; i++)        {            if(vis[0][i])            {                dp[i] = 1;                pre[i] = 0;            }        }        for(int i = 0; i < n; i++)        {            if(dp[i] == 1)                continue;            for(int j = 0; j < i; j++)            {                if(vis[j+1][i])                {                    if(dp[i] > dp[j]+1)                    {                        dp[i] = dp[j]+1;                        pre[i] = j+1;                    }                }            }        }        cout<<dp[n-1]<<endl;        int p = pre[n-1];        p--;        if(p != n-1)            flag[p] = 1;        while(p != -1)        {            p = pre[p];            p--;            if(p >= 0)                flag[p] = 1;        }        for(int i = 0; i < n; i++)        {            cout<<str[i];            if(flag[i])                cout<<" ";        }        puts("");    }}


0 0