블루 브릿지 컵 : 최대 동일한 시퀀스 (LCS) 메모리 문제 검색 알고리즘
375ms 재귀 적 방법에 비해, 속도 최적화는 매우 빠르고
문제 설명
제공된 X (I), Y (I )는, Z는 (i)는 단일 문자 후 X = {X (1), x는 (2) ... X (m)}, Y = {Y (1) 예를 ( 2) ..., Y (N)} , Z = {Z (1) Z (2) ... Z (K)} 우리 문자의 시퀀스를 전화, 상기 m, n 및 k는 문자 X의 시퀀스는, Y, Z 길이 괄호 () 첨자 문자 시퀀스로 지칭된다.
0보다 길이가 더 엄격 증가 첨자 서열 모든 J = 1,2, ... K에 대해, X (IJ) Z = (j를 가지고, {I1, I2 ...... IK} 본 예이면 ), 우리는 호출 Z는 X의 문자 시퀀스 인 모두 X와 Y의 Z 문자 시퀀스는 문자 시퀀스가있는 경우 또한, 우리는 X를 호출하고 Z는 공공 문자 시퀀스 Y.입니다
오늘날의 문제에서, 우리는 문자 순서의 일반적인 문자 시퀀스 X 주어진 두 Y의 최대 길이를 계산 여기에 우리 만 해당하는 최대 길이의 공통 부분 순서의 출력 값의 길이를 필요로합니다.
예를 들어, 문자 시퀀스 X = ABCD, Y = ACDE, 그때의 최대 길이는 이들 3, 서열 ACD 대응 일반적인 특성이다.
입력 포맷
입력 라인, 2 개 문자열이 스페이스에 의해 분리
출력 형식
의 문자 시퀀스에 대응하는 공통의 문자 시퀀스의 길이의 최대 길이의 두 출력값
샘플 입력
AABB AABB
샘플 출력
이
데이터 크기 및 규약
최대 100의 입력 스트링의 길이, 대소.
사고
당신은 재귀 트리를 보면, 우리는 것을 알 수 있습니다 중복 지점이 많이 이중 계산이되어있는 우리가 함께 계산 결과를 절약 할 수 있도록, 크게 시간 낭비, 결과가 계산되기 전에 얻을 수 있는지 여부를 재귀 전에 각 첫번째 확인 크게 시간을 절약 할 수 있습니다
- 맵의 결과는 2 차원 배열을 사용하므로 두 키 조회로 구성되기 때문에
int result[maxlen][maxlen]; // 存放结果
규칙 :
서브 문자열 앞에 LEN1 길이 S1은 스트링 SUB1 서브 문자열 LEN2 문자열 길이 S2가 SUB2 전에 인
S1 부분 문자열 [LEN1 전에 문자열 길이] 및 [LEN2 전에 S2 서브 문자열 길이] 같은 순서 sub_len의 긴 스트링 길이
S1 부분 문자열 [len1-1 전에 문자열 길이] 및 [LEN2 전에 S2 서브 문자열 길이] 같은 순서 sub_len1의 긴 스트링 길이
S1 부분 문자열 [LEN1 전에 문자열 길이]와 동일한 순서 sub_len2의 긴 스트링 길이 [len2-1 전에 S2 서브 문자열 길이]
- 마지막 SUB1과 SUB2 같은 경우 경우에 따라서, 그들은 + 1 sub_len 가장 긴 시퀀스의 길이와 동일
- SUB1과 SUB2 마지막 비트 다른, 그들은 가장 긴 시퀀스의 길이와 동일이 최대 인 경우 (sub_len1, sub_len2)
AC 전체 코드
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
#define max(a, b) ((a>b) ? (a) : (b))
#define maxlen 114
string s1, s2;
int result[maxlen][maxlen]; // 存放结果
/*
param len1 : s1串的前len1长度的子串 sub1
param len2 : s2串的前len2长度的子串 sub2
return : sub1 和 sub2 最大相同序列的长度
*/
int dp(int len1, int len2)
{
if(len1>=1 && len2>=1)
{
if(s1[len1-1] == s2[len2-1])
{
int l;
if(result[len1-1][len2-1])
{
return result[len1-1][len2-1] + 1;
}
else
{
l = dp(len1-1, len2-1);
result[len1-1][len2-1] = l;
}
return l + 1;
}
else
{
int l1;
if(result[len1-1][len2])
{
l1 = result[len1-1][len2];
}
else
{
l1 = dp(len1-1, len2);
result[len1-1][len2] = l1;
}
int l2;
if(result[len1][len2-1])
{
l2 = result[len1][len2-1];
}
else
{
l2 = dp(len1, len2-1);
result[len1][len2-1] = l2;
}
return max(l1, l2);
}
}
else
{
return 1;
}
}
int main()
{
memset(result, 0, sizeof(result)); // 初始全为0
cin>>s1>>s2;
cout<<(dp(s1.length(), s2.length())-1)<<endl;
return 0;
}