【poj 1692】Crossed Matchings (最长公共子序列变形)

来源:互联网 发布:淘宝掌柜推荐怎么设置 编辑:程序博客网 时间:2024/05/01 13:00

好吧,我的老实承认这几天写东西确实是不在状态,比较水,不,应该说是水爆了。

其实这道题很像最长公共祖先,为毛呢?

第一:有两条数列(虽然说了好像没说但是这确实是一个非常重要的提示)

第二:连接的线不能有其他的线交叉,说明可以把连线的两端之间看做最长公共祖先的一个数字,用这之间的一段来更新后面出现的情况(不知道你懂不懂)

区别就在于需要从两条队列中分别各自求出一个相同的值,so

#include<cstdio>#include<cstring>#include<iostream>#define maxn 123using namespace std;int n,m;int f[maxn][maxn],a[maxn],b[maxn];int main(){int T;scanf("%d",&T);while(T--){memset(f,0,sizeof(f));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",a+i);for(int i=1;i<=m;i++)scanf("%d",b+i);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])continue;int k,h;for(k=j-1;k>0;k--)if(b[k]==a[i])break;for(h=i-1;h>0;h--)if(a[h]==b[j])break;if(k!=0&&h!=0)f[i][j]=max(f[i][j],f[h-1][k-1]+2);}}printf("%d\n",f[n][m]);}return 0;}


0 0