回文の部分文字列のマージ------------------------------------思考(最長回文文字の間隔dp文字列)

ここに画像の説明を挿入
ここに画像の説明を挿入

この記事では、最初に次のことを述べます。最も長い回文の文字列長を解決するための動的プログラミング

f [i] [j]:s [i]からs [j]で表される部分文字列が回文列であるかどうかを示し、1は0です。s
[i]とs [j]が等しいかどうかに応じてパーティション

1.s [i] == s [j]、s [i + 1]からs [j-1]が回文サブストリングである限り、s [i]からs [j]は回文サブストリングでなければなりません。s [i + 1]からs [j-1]が回文サブストリングでない場合、s [i]からs [j]も回文サブストリングであってはなりません。

2.s [i]!= S [j]次に、s [i]からs [j]は回文の部分文字列であってはなりません

状態方程式:

ここに画像の説明を挿入

この質問に戻ります。この質問は2つの文字列だからです。2Dを4Dに拡張します

f [sa] [ea] [sb] [eb]:回文サブストリングを構成できるsa〜eaおよびb sb〜ebの最大長を示します

伝達方程式:

	if(a[sa]==a[ea])  f[sa][ea][sb][eb]|=f[sa+1][ea-1][sb][eb];
	if(b[sb]==b[eb])  f[sa][ea][sb][eb]|=f[sa][ea][sb+1][eb-1];
	if(a[sa]==b[eb])  f[sa][ea][sb][eb]|=f[sa+1][ea][sb][eb-1];
	if(a[ea]==b[sb])  f[sa][ea][sb][eb]|=f[sa][ea-1][sb+1][eb];

#include<bits/stdc++.h>
using namespace std;
const int N=55;
int f[N][N][N][N];
int t;
char a[N],b[N];
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%s %s",(a+1),(b+1));
		int ans=-1;
		int lena=strlen(a+1);
		int lenb=strlen(b+1);
		for(int la=0;la<=lena;la++) //枚举a串的长度
			for(int lb=0;lb<=lenb;lb++)//枚举b串的长度
			{
				for(int sa=1;sa+la-1<=lena;sa++) //枚举a串起点
				{
					for(int sb=1;sb+lb-1<=lenb;sb++)//枚举b串起点
					{
						int ea=sa+la-1;int eb=sb+lb-1;//a,b串终点
						if(la+lb<=1) f[sa][ea][sb][eb]=1;//长度为1的串,初始化为1
						else
						{
							f[sa][ea][sb][eb]=0;
							if(a[sa]==a[ea]) f[sa][ea][sb][eb]|=f[sa+1][ea-1][sb][eb];
							if(b[sb]==b[eb]) f[sa][ea][sb][eb]|=f[sa][ea][sb+1][eb-1];
							if(a[sa]==b[eb])  f[sa][ea][sb][eb]|=f[sa+1][ea][sb][eb-1];
							if(a[ea]==b[sb]) f[sa][ea][sb][eb]|=f[sa][ea-1][sb+1][eb];
							
						}
						//1表示是回文串,所以取长度la+lb
						if(f[sa][ea][sb][eb])  ans=max(ans,la+lb);
					}
				}
			}
		cout<<ans<<endl;
	 } 
}
公開された元の記事572件 賞賛された14件 ビュー10,000件以上

おすすめ

転載: blog.csdn.net/qq_43690454/article/details/105282586