题目描述:
Although Haneen was able to solve the LCS problem, Dr. Ibrahim is suspicious about whether she really understands the LCS problem or not. He believes that she can't write the code on her own, but can only translate the LCS pseudo-code given in class into C++ code without really understanding how it works. Here is the pseudo-code Dr. Ibrahim gave in class:
function LCS (A[1..R], B[1..C])
DP = array(0..R, 0..C)
for i := 0..R
DP[i,0] = 0
for j := 0..C
DP[0,j] = 0
for i := 1..R
for j := 1..C
if A[i] = B[j]
DP[i,j] := DP[i-1,j-1] + 1
else
DP[i,j] := max(DP[i,j-1], DP[i-1,j])
return DP[R,C]
To verify that Haneen understands the LCS problem, Dr. Ibrahim asked her to solve the following problem:
After running the above LCS code on two strings A and B, the 2D array DP is filled with values. Given the 2D array DP, can you guess what A and B are? Any two strings A and B that will produce the given table and contain only lowercase English letters are acceptable.
Can you help Haneen solve this problem?
Input
The first line of input contains two integers R and C (1 ≤ R, C ≤ 25), the length of the strings A and B, respectively.
Each of the following R + 1 lines contains C + 1 integers, these lines represent the 2D array DP.
It's guaranteed that the given table was produced by running the algorithm on two strings that contain only lowercase English letters.
Output
Print string A on the first line and string B on the second line. Both strings should contain only lowercase English letters.
Example
Input
3 4
0 0 0 0 0
0 0 1 1 1
0 0 1 1 2
0 1 1 1 2
Output
abc
cadb
大意:给你一个由两个序列求lcs打出的dp表 求出这两个序列
分暴力和并查集两种做法(暴力的勉强理解,并查集还看不懂,有待后续更新)
暴力法:
当我们得到(dp[a1][b1]==dp[a1-1][b1-1]+1&&dp[a1][b1]!=max(dp[a1-1][b1],dp[a1][b1-1]))这个式子时
我们可以得出a[a1]==b[b1]
因为字符串长度<=25,然后可以先假设A字符串就是abcdef....,然后根据A算B就行。b[j]未确定时,令b[j]=a[i]即可;遇到b[j]已确定的情况就改变a[i],以及所有跟a[i]相同的字符。(包括a数组和b数组中所有等于a[i]的字符,因为这个a[i]可能本身是一个未确定的值,所以由这个未确定的a[i]得到的此前的b[j]和此前的a[i]都要改变)
最后遇到没有被访问过的b[j]时,只需要将b[j]赋值为再a中没有出现过的字母即可(或者直接赋值为z,因为字符长度小于等于25)
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<algorithm>
using namespace std;
int main()
{
int a,b;
cin>>a>>b;
int dp[30][30],visb[30];
char al[30],bl[30];
Me0(dp);
Me0(visb);
for(int a1=0;a1<=a;a1++)
{
for(int b1=0;b1<=b;b1++)
{
cin>>dp[a1][b1];
}
}
for(int a1=0;a1<a;a1++)
{
al[a1]='a'+a1;
}
al[a]=bl[b]='\0';
for(int a1=1;a1<=a;a1++)
{
for(int b1=1;b1<=b;b1++)
{
if(dp[a1][b1]==dp[a1-1][b1-1]+1&&dp[a1][b1]!=max(dp[a1-1][b1],dp[a1][b1-1]))
{
if(visb[b1-1]==0)
{
bl[b1-1]=al[a1-1];
visb[b1-1]=1;
}
else
{
for(int k=0;k<b;k++)
{
if(bl[k]==al[a1-1])
{
bl[k]=bl[b1-1];
}
}
for(int k=0;k<a;k++)
{
if(al[k]==al[a1-1]&&k!=a1-1)
{
al[k]=bl[b1-1];
}
}
al[a1-1]=bl[b1-1];
}
}
}
}
int flag[26];
Me0(flag);
for(int a1=0;a1<a;a1++)
{
flag[al[a1]-'a']=1;
}
int temp;
for(int a1=0;a1<26;a1++)
{
if(flag[a1]==0)
{
temp=a1;
break;
}
}
for(int b1=0;b1<b;b1++)
{
if(visb[b1]==0)
{
bl[b1]=temp+'a';
}
}
printf("%s\n%s\n",al,bl);
}