hdu 1513 && poj 1159 线性dp回文字符串

这道题的大意是:给你任意一个字符串(字符串中字符只可能在 a-z  && A-Z && 0-9中)例如:Ab3bd,找出最少再填几个字符能构成回文字符串;(回文字符串也就是从左向右读和从右向左读是一样的)。那么易知题例就是最少需要2个Ad;

题目的输入:第一行n:代表有多少个字符。第二行代表输入的字符串

输出:输出最少需要几个字符才能使输入的字符串构成回文字符串

这道题如果直接做感觉太有难度。。。翻译一下之后就会发现简单很多:其实就是两个字符串找最长公共子序列的长度,而这两个字符串就是一个正序,一个逆序。这样问题就变得简单了,但是我们还需要注意另一个问题,就是 n<=5000;如果我们用普通的做法来做建一个 int a[5001][5001]的话,算一下内存占用,肯定是超过了65536k,这样就会 mlo;这个时候就要想到用滚动数组,就变成了int a[2][5001];就不会超内存了;

下面是代码:

#include<stdio.h>
#include<string.h>
char str[6000];
int dp[2][6000];
int max(int x,int y)
{
    return (x>y?x:y);
}
int main()
{
    //freopen("test.txt","r",stdin);
    int n;
    scanf("%d",&n);
    str[0]='#';
    scanf("%s",&str[1]);
    memset(dp,0,sizeof(dp));
    int num=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(str[i]==str[n+1-j])
                dp[i%2][j]=dp[(i+1)%2][j-1]+1;
            else
                dp[i%2][j]=max(dp[(i+1)%2][j],dp[i%2][j-1]);
            if(num<dp[i%2][j])
                num=dp[i%2][j];
        }
    }
    printf("%d\n",n-num);
    return 0;
}

posted @ 2014-07-30 22:16  hqwhqwhq  阅读(117)  评论(0编辑  收藏  举报