首页 > 代码库 > POJ 1159 Palindrome(滚动数组)

POJ 1159 Palindrome(滚动数组)

链接:click here

题意:

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

思路:

设a[i]是这个字符串,b[i]是这个字符串的逆序串。那么a[i],b[i]的最长公共子序列就是所求的字符串里拥有的最大的回文串。然后用总串长减去最大的回文串长度即为所求。求最长公共子序列的公式为:dp[i][j]=max(dp[i-1] [j],dp[i][j-1])if(a[i]==b[i])dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);

如果直接求的话,会超时。

用两种解决方法:

1,shor int数组

2,运用动态数组。

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

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

 代码:

<span style="font-size:12px;">#include <iostream>
#include <stdio.h>
#include <string.h>
#define  max(a,b) (a>b?a:b)
using namespace std;
const int maxn=5005;
const int inf = 0x3f3f3f3f;
short int dp[maxn][maxn];
int a[maxn],b[maxn];
int n,m,i,j,length;
inline int input()
{
    int res=0,f=1,c;
    while(!isdigit(c = getchar()) && c!='-');
    c=='-' ? f=0 : res=c-'0';
    while(isdigit(c = getchar()))
        res = res*10 + c-'0';
    return f ? res : -res;
}
int main()
{
    char str;
    //n=input();       //POJ 竟然不支持快速输入,写成这样返回WA
    scanf("%d",&n);
    getchar();
    for(i=1; i<=n; i++)
    {
        scanf("%c",&str);
        a[i]=str;
        b[n-i+1]=str;
    }
    for(i=0; i<=n; i++)
    {
        dp[i][0]=0;
        dp[0][i]=0;
    }
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=n; j++)
        {
            dp[i][j]=max(dp[i][j-1],dp[i-1][j]);
            if(a[i]==b[j])
            {
                dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);   //关键
            }
        }
    }
    length=dp[n][n];
    printf("%d\n",n-length);                            //总长减去回文子长即为所求
    return 0;
}
</span>

滚动数组:

<span style="font-size:12px;">#include <iostream>
#include <stdio.h>
#include <string.h>
#define  max(a,b) (a>b?a:b)
using namespace std;
const int maxn=5005;
const int inf = 0x3f3f3f3f;
short int dp[maxn][maxn];
int a[maxn],b[maxn];
int n,m,i,j,length;
inline int input()
{
    int res=0,f=1,c;
    while(!isdigit(c = getchar()) && c!='-');
    c=='-' ? f=0 : res=c-'0';
    while(isdigit(c = getchar()))
        res = res*10 + c-'0';
    return f ? res : -res;
}
int main()
{
    char str;
    //n=input();      
    scanf("%d",&n);
    getchar();
    for(i=1; i<=n; i++)
    {
        scanf("%c",&str);
        a[i]=str;
        b[n-i+1]=str;
    }
    dp[1][0]=dp[0][0]=0;
    for(i=0; i<=n; i++)
    {
        //dp[i][0]=0;
        dp[0][i]=0;
    }
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=n; j++)
        {
            dp[i%2][j]=max(dp[i%2][j-1],dp[(i-1)%2][j]);
            if(a[i]==b[j])
            {
                dp[i%2][j]=max(dp[i%23][j],dp[(i-1)%2][j-1]+1);
            }
        }
    }
    length=dp[n%2][n];
    printf("%d\n",n-length);
    return 0;
}
</span>



POJ 1159 Palindrome(滚动数组)