ブルーブリッジカップ:まで同じシーケンス(LCS)メモリの問題検索アルゴリズムへ
375ms再帰的方法と比較して、速度のために最適化は非常に高速であります
問題説明
提供X(I)、Y(I )、Z(i)はX = {X(1)X次いで、単一の文字を表す (2)... X(M)}、Y = {Y(1)、Y( 2)...... Y(N)} 、Z = {Z(1)、Z(2)...... Z(K)}、 m、nおよびkは文字X、Yの配列である、我々は、文字のシーケンスを呼び出しますZの長さ、括弧()は、添え字文字列で参照されます。
長さ0より大きく、厳密添字配列を増加させるが存在する場合、{I1、I2 ... IK}、全てのj = 1,2、... kに対して、X(IJ)= Z(Jを有するように )、 我々は呼び出しZは、Xの文字列であります XとYの両方のZの文字列は文字の配列である場合にはまた、我々はXとZは、公共の文字列で呼び出すY.
今日の問題で、私たちは、与えられた2の文字列の一般的な文字列XとYの最大の長さを計算したい、ここで我々が対応する最大の長さの共通部分列の出力値の長さのみを必要としています。
例えば、文字シーケンスX = ABCD、Y = ACDE、最大長が3であり、対応する共通文字列は、ACD。
入力形式の
2つの文字列がスペースで区切られた入力ライン
の出力フォーマット
文字の配列に対応する共通の文字列の長さの最大長さの両方の出力値を
サンプル入力
AABB AABB
サンプル出力
2
データサイズと表記
100までの入力文字列の長さ、大文字と小文字を区別。
思考
あなたは再帰的なツリーを見れば、我々はそれを見ることができ、重複支店の多くはダブルカウントがされている私たちが一緒に計算結果を保存しますので、非常に時間の無駄、その結果が計算される前に取得するかどうかを再帰前に、それぞれの最初のチェックを大幅に時間を節約することができます
- マップの結果は、二次元アレイを使用するように、二つの重要なクエリで構成されているよう
int result[maxlen][maxlen]; // 存放结果
表記:
LEN2文字列の長さs2はSUB2になる前に、サブ文字列の前にLEN1長s1が文字列SUB1、サブ文字列であります
【LEN2前S2サブストリングの長さ]ストリングS1 [LEN1前に文字列の長さ]と同じシーケンスsub_lenの最長文字列の長さ
【LEN2前S2サブストリングの長さ]ストリングS1 [len1-1前に文字列の長さ]と同じシーケンスsub_len1の最長文字列の長さ
同じシーケンスsub_len2の最長文字列の長さ[len2-1前S2サブストリングの長さ]ストリングS1 [LEN1前に文字列の長さ]と
- だから、同じことが、その後、彼らは最も長いシーケンスの長さと同じであれば、最後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;
}