题意
题意就是给出两个数列a和b,一个交错匹配是这样:
如果匹配之后连了线,交叉能且只能出现一次。
求出这两个数列最大的匹配数。
题解
先设出状态把。
显然每次我们都要判断a[i]和b[j]是否和前面的数形成一个交错匹配。
如果 不形成匹配,那么就
如果 形成匹配,假设数列 中和 匹配的数的位置最靠后的是 ,数列 中和 匹配的数的位置最靠后的是 。
那么就有
这里为什么一定是最靠后的呢?
因为我们可以显然发现,若 ,则有
那么就ok了。
code
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int num=0;
bool flag=true;
char c=' ';
for(;c>'9'||c<'0';c=getchar())
if(c=='-')
flag=false;
for(;c>='0'&&c<='9';num=num*10+c-48,c=getchar());
return flag ? num : -num;
}
const int maxn=210;
int n,m,a[maxn],b[maxn];
void init()
{
n=read();
m=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=m;i++)
b[i]=read();
}
int f[maxn][maxn];
void DP()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(a[i]!=b[j])
{
int ti,tj;
for(ti=i;ti>=1;ti--)
if(a[ti]==b[j])break;
for(tj=j;tj>=1;tj--)
if(b[tj]==a[i])break;
//找到最靠后的匹配位置
if(ti!=0&&tj!=0)
f[i][j]=max(f[i][j],f[ti-1][tj-1]+2);
}
}
printf("%d\n",f[n][m]);
}
int main()
{
init();
DP();
return 0;
}