POJ 1159 Palindrome

 

#include<cstdio>

#include<cstring>

#include<cstdlib>

#define MAXN 5005

#define max(a, b) ( a > b ? a : b)

short f[MAXN][MAXN], len;

char a[MAXN], b[MAXN];



void rev()

{

    for( int i = len, j = 1; i >= 1; i --, j ++)

    {

        b[j] = a[i];

    }

}



void dp()

{

    memset( f, 0, sizeof f);

    for( int i = 1; i <= len; i ++)

        for( int j = 1; j <= len; j ++)

        {

            if( a[i] == b[j])

                f[i][j] = f[i - 1][j - 1] + 1;

            else

                f[i][j] = max( f[i - 1][j], f[i][j - 1]);

        }

}



int main()

{

    while( scanf( "%d", &len) != EOF)

    {

        scanf( "%s", a + 1);

        rev();

        dp();

        printf( "%d\n", len - f[len][len]);

    }

    return 0;

}

 

 

  题目问的是最少几步可以将原串变成回文串,其实就是原串长度减去原串与逆置串最长

公共子序列的长度。这里int超内存,用short来存储。还有另一个就是用滚动数组,这里不是

很明白...

 

#include<stdio.h>

#include<string.h>

#include<stdlib.h>

const int MAXN = 5005;

int dp[MAXN], prei, prej, len;

char a[MAXN];

int max(int a, int b)

{return a > b ? a : b;}

int main()

{

    int i, j;

    while(scanf("%d", &len) != EOF)

    {

        memset(dp, 0, sizeof(dp));

        scanf("%s", a);

        prej = prei = 0;

        for(i = 0; i < len; ++ i)

        {

            prej = 0;

            for(j = 0; j < len; ++ j)

            {

                prei = dp[j + 1];

                if(a[i] == a[len - j - 1])

                    dp[j + 1] = prej + 1;

                else

                    dp[j + 1] = max(dp[j + 1], dp[j]);

                prej = prei;

            }

        }

        printf("%d\n", len - dp[len]);

    }

    return 0;

}

 

 

你可能感兴趣的:(poj)