TRIP-LCS方案输出

首先肯定是要求lcs的,这个我懒得讲了。。。

因为lcs最多就是这个串的长度,所以我们可以考虑dfs。我们开2个数组,f1[i][j]表示在a串中,f2[i][j]表示在b串中,j之前的第一个‘a’+j在什么地方。

因为我们递归的时候知道了lcs的长度,所以我们可以用枚举每一位是啥的方式递归。(26^80emmmm但是可以剪枝)

因为知道了每一位是啥,所以我们就可以轻易求出上一个的位置。如果这个位置不存在,那就不太行。递归返回。

如果存在就比较ok,就继续递归。。。

#include <bits/stdc++.h>

using namespace std;
const int maxn=1005;
int T;int tot=0;
string s1,s2;
int f[maxn][maxn],f1[maxn][maxn],f2[maxn][maxn];
string ans[maxn];
void print(int i,int j)
{
	if(i==0||j==0) return;
	if(f[i][j]==f[i-1][j-1]+1)
	{
		print(i-1,j-1);
		
	}
}
void find(int n1,int n2,string s,int l)
{
	if(n1<0||n2<0) return ;
	if(l<=0) {ans[++tot]=s;return;}
	for(int i=1;i<=26;i++)
	{
		int p1=f1[i][n1],p2=f2[i][n2];
		if(f[p1][p2]!=l) continue;
		char ch=i+96;
		find(p1-1,p2-1,ch+s,l-1);
	}
}
void work()
{
	tot=0;
	cin>>s1>>s2;
	int n1=s1.size(),n2=s2.size();
	s1='.'+s1;s2='.'+s2;
	memset(f,0,sizeof(f));memset(f1,0,sizeof(f1));memset(f2,0,sizeof(f2));
	for(int i=1;i<=26;i++)
	{
		for(int j=1;j<=n1;j++)
		{
			if(s1[j]==i+96) f1[i][j]=j;
			else f1[i][j]=f1[i][j-1];
		}
		for(int j=1;j<=n2;j++)
		{
			if(s2[j]==i+96) f2[i][j]=j;
			else f2[i][j]=f2[i][j-1];
		}
	}
	for(int i=1;i<=n1;i++)
	{
		for(int j=1;j<=n2;j++)
		{
			f[i][j]=max(f[i-1][j],f[i][j-1]);
			if(s1[i]==s2[j])
			{
				f[i][j]=max(f[i][j],f[i-1][j-1]+1);
			}
		}
	}
	find(n1,n2,"",f[n1][n2]);
//	cout<<f[n1][n2]<<endl;
//	print(n1,n2);
	sort(ans+1,ans+1+tot);
	for(int i=1;i<=tot;i++) cout<<ans[i]<<endl;
}
int main()
{
	scanf("%d",&T);
	for(int ti=1;ti<=T;ti++)
	{
		work();
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值