// top down approach
#include<bits/stdc++.h>
using namespace std;
void findStr(int i, int j, string x, string y, string sub_str, vector<vector<int>>&lookup)
{
if(i == 0 || j == 0)
{
reverse(sub_str.begin(), sub_str.end());
cout<<sub_str<<endl;
return;
}
if(x[i] == y[j])
{
sub_str += x[i];
findStr(i - 1, j - 1, x, y, sub_str, lookup);
}
else
{
if(lookup[i][j - 1] > lookup[i - 1][j])
findStr(i, j - 1, x, y, sub_str, lookup);
else if(lookup[i][j - 1] < lookup[i - 1][j])
findStr(i - 1, j, x, y, sub_str, lookup);
else
{
findStr(i, j - 1, x, y, sub_str, lookup);
findStr(i - 1, j, x, y, sub_str, lookup);
}
}
}
void findString(int m, int n, string x, string y, vector<vector<int>>&lookup)
{
int i = m, j = n;
string sub_str = "";
findStr(i, j, x, y, sub_str, lookup);
return;
}
int lc_subsequence(int i, int j, string x, string y, vector<vector<int>>&lookup)
{
if(lookup[i][j] < INT_MAX)
return lookup[i][j];
if(x[i] == y[j])
lookup[i][j] = 1 + lc_subsequence(i - 1, j - 1, x, y, lookup);
else
{
lookup[i][j] = max(lc_subsequence(i - 1, j, x, y, lookup), lc_subsequence(i, j - 1, x, y, lookup));
}
return lookup[i][j];
}
int memoized_top_down(string x, string y)
{
int m = x.length();
int n = y.length();
x = "a" + x; // prefixed by some character for making index from 1
y = "a" + y;
vector<vector<int>>lookup(m+1, vector<int>(n+1));
for(int i = 0; i <= m; i++)
{
for(int j = 0; j <= n; j++)
{
if(i == 0 || j == 0)
lookup[i][j] = 0;
else
lookup[i][j] = INT_MAX;
}
}
int ans = lc_subsequence(m, n, x, y, lookup);
// print all possible subsequence
findString(m, n, x, y, lookup);
return ans;
}
int main()
{
string x, y;
cin>>x>>y;
int ans = memoized_top_down(x, y);
cout<<"length of largest subsequence : "<<ans<<endl;
return 0;
}
Ly8gdG9wIGRvd24gYXBwcm9hY2gKCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7Cgp2b2lkIGZpbmRTdHIoaW50IGksIGludCBqLCBzdHJpbmcgeCwgc3RyaW5nIHksIHN0cmluZyBzdWJfc3RyLCB2ZWN0b3I8dmVjdG9yPGludD4+Jmxvb2t1cCkKewoJaWYoaSA9PSAwIHx8IGogPT0gMCkKCXsKCQlyZXZlcnNlKHN1Yl9zdHIuYmVnaW4oKSwgc3ViX3N0ci5lbmQoKSk7CgkJY291dDw8c3ViX3N0cjw8ZW5kbDsKCQlyZXR1cm47Cgl9CglpZih4W2ldID09IHlbal0pCgl7CgkJc3ViX3N0ciArPSB4W2ldOwoJCWZpbmRTdHIoaSAtIDEsIGogLSAxLCB4LCB5LCBzdWJfc3RyLCBsb29rdXApOwoJfQoJZWxzZQoJewoJCWlmKGxvb2t1cFtpXVtqIC0gMV0gPiBsb29rdXBbaSAtIDFdW2pdKQoJCQlmaW5kU3RyKGksIGogLSAxLCB4LCB5LCBzdWJfc3RyLCBsb29rdXApOwoJCWVsc2UgaWYobG9va3VwW2ldW2ogLSAxXSA8IGxvb2t1cFtpIC0gMV1bal0pCgkJCWZpbmRTdHIoaSAtIDEsIGosIHgsIHksIHN1Yl9zdHIsIGxvb2t1cCk7CgkJZWxzZQoJCXsKCQkJZmluZFN0cihpLCBqIC0gMSwgeCwgeSwgc3ViX3N0ciwgbG9va3VwKTsKCQkJZmluZFN0cihpIC0gMSwgaiwgeCwgeSwgc3ViX3N0ciwgbG9va3VwKTsKCQl9Cgl9Cn0KCnZvaWQgZmluZFN0cmluZyhpbnQgbSwgaW50IG4sIHN0cmluZyB4LCBzdHJpbmcgeSwgdmVjdG9yPHZlY3RvcjxpbnQ+PiZsb29rdXApCnsKCWludCBpID0gbSwgaiA9IG47CglzdHJpbmcgc3ViX3N0ciA9ICIiOwoJZmluZFN0cihpLCBqLCB4LCB5LCBzdWJfc3RyLCBsb29rdXApOwoJcmV0dXJuOwp9CgppbnQgbGNfc3Vic2VxdWVuY2UoaW50IGksIGludCBqLCBzdHJpbmcgeCwgc3RyaW5nIHksIHZlY3Rvcjx2ZWN0b3I8aW50Pj4mbG9va3VwKQp7CglpZihsb29rdXBbaV1bal0gPCBJTlRfTUFYKQoJCXJldHVybiBsb29rdXBbaV1bal07CglpZih4W2ldID09IHlbal0pCgkJbG9va3VwW2ldW2pdID0gMSArIGxjX3N1YnNlcXVlbmNlKGkgLSAxLCBqIC0gMSwgeCwgeSwgbG9va3VwKTsKCWVsc2UKCXsKCQlsb29rdXBbaV1bal0gPSBtYXgobGNfc3Vic2VxdWVuY2UoaSAtIDEsIGosIHgsIHksIGxvb2t1cCksIGxjX3N1YnNlcXVlbmNlKGksIGogLSAxLCB4LCB5LCBsb29rdXApKTsKCX0KCXJldHVybiBsb29rdXBbaV1bal07Cn0KCmludCBtZW1vaXplZF90b3BfZG93bihzdHJpbmcgeCwgc3RyaW5nIHkpCnsKCWludCBtID0geC5sZW5ndGgoKTsKCWludCBuID0geS5sZW5ndGgoKTsKCXggPSAiYSIgKyB4OwkvLyBwcmVmaXhlZCBieSBzb21lIGNoYXJhY3RlciBmb3IgbWFraW5nIGluZGV4IGZyb20gMQoJeSA9ICJhIiArIHk7Cgl2ZWN0b3I8dmVjdG9yPGludD4+bG9va3VwKG0rMSwgdmVjdG9yPGludD4obisxKSk7Cglmb3IoaW50IGkgPSAwOyBpIDw9IG07IGkrKykKCXsKCQlmb3IoaW50IGogPSAwOyBqIDw9IG47IGorKykKCQl7CgkJCWlmKGkgPT0gMCB8fCBqID09IDApCgkJCQlsb29rdXBbaV1bal0gPSAwOwoJCQllbHNlCgkJCQlsb29rdXBbaV1bal0gPSBJTlRfTUFYOwoJCX0KCX0KCWludCBhbnMgPSBsY19zdWJzZXF1ZW5jZShtLCBuLCB4LCB5LCBsb29rdXApOwoJLy8gcHJpbnQgYWxsIHBvc3NpYmxlIHN1YnNlcXVlbmNlCglmaW5kU3RyaW5nKG0sIG4sIHgsIHksIGxvb2t1cCk7CglyZXR1cm4gYW5zOwp9CgppbnQgbWFpbigpCnsKCXN0cmluZyB4LCB5OwoJY2luPj54Pj55OwoJaW50IGFucyA9IG1lbW9pemVkX3RvcF9kb3duKHgsIHkpOwoJY291dDw8Imxlbmd0aCBvZiBsYXJnZXN0IHN1YnNlcXVlbmNlIDogIjw8YW5zPDxlbmRsOwoJcmV0dXJuIDA7Cn0=