poj 1159 palindrome

转:https://i-blog.csdnimg.cn/blog_migrate/a2c0214765c91ded32ff1791430eac34.png

题意:

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

做法:

设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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值