poj 1159 palindrome

来源:互联网 发布:巴西语翻译软件 编辑:程序博客网 时间:2024/05/21 07:04

转:http://blog.csdn.net/rowanhaoa/article/details/8543899

题意:

给你一串字符串,让你求最少加入几个字符,才能使得这个字符串是个回文串。

做法:

设a[i]是这个字符串,b[i]是这个字符串的逆序串。

那么a[i],b[i]的最长公共子序列就是所求的字符串里拥有的最大的回文串。

然后用总串长减去最大的回文串长度即为所求。

如果直接求的话,势必要开一个5001*5001的数组,铁定MLE。

有一下两种解决方法:

1,开short int型数组

这是poj返回的结果:

2,运用动态数组。

根据dp滚动的过程我们可以知道,dp【i】【j】的值不会与dp[i-2][0.....n]的值有关系。

那么可以把dp[i][j]的值覆盖到dp[i-2][j]上。即dp[i][j]为dp[i%2][j];

poj返回的结果:

对比以上两种方法,显而易见的可以得出2的方法很节约空间,就是耗时略


代码(原)

#include <iostream>#include <stdio.h>#include <algorithm>#include <set>#include <string>using namespace std;int main(){    int w[2][5010];    char a[5010];    char b[5010];    int n;    while(scanf("%d",&n)!=EOF)    {        getchar();        for(int i=1;i<=n;i++)        {            scanf("%c",&a[i]);            b[n-i+1]=a[i];        }        for(int i=0;i<=n;i++) //a的长度为0时            w[0][i]=0;        w[1][0]=0;   //a的长度为1时        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                if(a[i]==b[j])                    w[i%2][j]=w[(i-1)%2][j-1]+1;                else                    w[i%2][j]=max(w[(i-1)%2][j],w[i%2][j-1]);            }        }       printf("%d\n",n-w[n%2][n]);    }    return 0;}



原创粉丝点击