IT民工
加油!

 

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

 

 

posted on 2012-04-11 12:43  找回失去的  阅读(128)  评论(0编辑  收藏  举报