POJ1159 DPorLCS妙用

POJ1159 DP or LCS妙用

一开始用的DP做,dp[i][j]表示从i到j这个区间成为回文需要增加多少个字符,如果s[i]==s[j],那么dp[i][j]=dp[i+1][j-1],否则dp[i][j]=min(dp[i+1][j],dp[i][j-1])+1,状态转移方程应该不难理解,不过注意的是开了5000*5000的int数组会MLE,用了short类型飘过…
做完搜了搜题解,居然是逆序求一次LCS,然后用len-LCS()就好了,仔细想一想好像还真是…
另外优化空间可以用滚动数组…不过我还不会…

Description

A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order to obtain a palindrome.

As an example, by inserting 2 characters, the string “Ab3bd” can be transformed into a palindrome (“dAb3bAd” or “Adb3bdA”). However, inserting fewer than 2 characters does not produce a palindrome.

Input

Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from ‘A’ to ‘Z’, lowercase letters from ‘a’ to ‘z’ and digits from ‘0’ to ‘9’. Uppercase and lowercase letters are to be considered distinct.

Output

Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.

Sample Input

5
Ab3bd

Sample Output

2

代码一

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
using namespace std;

short dp[5001][5001];
char s[5001];
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",s+1);
     for (int i = n;i>=0;i--)
    {
       // dp[i][i] = 0;
       for (int j = 1;j<=n;j++)
        {
           if (i==j)
                continue;
           if (s[i]==s[j])
                dp[i][j] = dp[i+1][j-1];
           else
                dp[i][j] = min(dp[i+1][j],dp[i][j-1])+1;
        }
    }
    printf("%d\n",dp[1][n]);
}

代码二

#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
short v[5001][5001];
string A,B;
int r,c;
int LCS()
{
        for(int i=1;i<=r;i++)
                for(int j=1;j<=c;j++)
                {
                       if(A[i-1]==B[j-1])
                        {
                                v[i][j]= v[i-1][j-1]+1;
                        }
                        else if(v[i-1][j]>=v[i][j-1])
                        {
                                v[i][j]=v[i-1][j];
                        }
                        else
                        {
                                v[i][j]=v[i][j-1];
                        }
                }
        return v[r][c];
}
int main()
{
  int n;
  scanf("%d",&n);
  cin >>A;

  B.assign(A.rbegin(), A.rend());
  r=A.size(),c=B.size();
  printf("%d\n",n-LCS());

    return 0;
}

你可能感兴趣的:(POJ1159 DPorLCS妙用)