poj1159--Palindrome(dp: 최장 공통 하위 시퀀스 변형 + 스크롤 배열)

3490 단어
Palindrome
Time Limit: 3000MS
 
Memory Limit: 65536K
Total Submissions: 53414
 
Accepted: 18449
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

Source
IOI 2000
제목 대의: 최소한의 문자를 추가하여 문자열을 회문열로 바꿉니다
만약 문자열이 회문열이라면, 문자열은 역순 그룹의 가장 긴 공통 서열과 자신의 길이이기 때문에, 가장 긴 공통 서열의 길이를 구한 후, 전체 길이로 그것을 빼면 수정할 길이를 얻을 수 있다.
short의 5000*5000 배열 사용하기
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
short dp[5100][5100] ;
char str1[5100] , str2[5100] ;
int main()
{
    int i , j , n ;
    while(scanf("%d", &n) !=EOF)
    {
        scanf("%s", str1);
        for(i = 0 ; i < n ; i++)
            str2[n-1-i] = str1[i] ;
        str2[i] = '\0' ;
        for(i = 1 ; i <= n ; i++)
            for(j = 1 ; j <= n ; j++)
            {
                if( str1[i-1] == str2[j-1] )
                    dp[i][j] = dp[i-1][j-1]+1 ;
                else
                    dp[i][j] = max( dp[i-1][j],dp[i][j-1] );
            }
        printf("%d
", n-dp[n][n]); } return 0; }

스크롤 배열 사용
스크롤 그룹: 두 줄의 그룹을 사용하여 큰 2차원 그룹을 시뮬레이션합니다
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[2][5100] ;
char str1[5100] , str2[5100] ;
int main()
{
    int i , j , n , k ;
    while(scanf("%d", &n) !=EOF)
    {
        scanf("%s", str1);
        for(i = 0 ; i < n ; i++)
            str2[n-1-i] = str1[i] ;
        str2[i] = '\0' ;
        k = 0 ;
        for(i = 1 ; i <= n ; i++)
        {
            k = 1 - k ;
            for(j = 1 ; j <= n ; j++)
            {
                if( str1[i-1] == str2[j-1] )
                    dp[k][j] = dp[1-k][j-1]+1 ;
                else
                    dp[k][j] = max( dp[1-k][j],dp[k][j-1] );
            }
        }
        printf("%d
", n-dp[k][n]); } return 0; }

좋은 웹페이지 즐겨찾기