COGS 597 交错匹配 题解

来源:互联网 发布:163邮箱设置smtp 端口 编辑:程序博客网 时间:2024/05/07 01:34

【问题描述】
    有两行自然数, UP[1..N] , DOWN[1..M] ,如果 UP[I]=DOWN[J]=K ,那么上行的第 I 个位置的数就可以跟下行的第 J 个位置的数连一条线,称为一条 K 匹配,但是 同一个位置 的数最多只能连一条线。另外,每个 K 匹配都 必须且至多 跟一个 L 匹配相交且 K ≠ L !现在要求一个最大的匹配数。

【输入格式】 
    第一行有两个正整数 N 和 M 。第二行 N 个 UP 的自然数,第三行 M 个 DOWN 的自然数。其中 0<N 、 M<=200 , UP 、 DOWN 的数都不超过 32767 。

【输出格式】 
   最大匹配数 。

【输入输出样例1】 
输入:

crossa.in12 111 2 3 3 2 4 1 5 1 3 5 103 1 2 3 2 4 12 1 5 5 3

输出:

crossa.out8

【输入输出样例2】 
输入:

crossa.in4 41 1 3 31 1 3 3

输出:

crossa.out0

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++



ps:比较坑的是……COGS和学校测得文件名不一样,害得我无输出了好几次……

++++++++++++++++++++++++++++代码如下+++++++++++++++++++++++++++++++++++++++

#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>using namespace std;int m,n,z,f[300][300],v[300][300],u[300][300],a[300],b[300];int main(){freopen("cross.in","r",stdin);freopen("cross.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)scanf("%d",&a[i]);for(int j=1;j<=m;j++)scanf("%d",&b[j]);for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {v[i][j]=0;u[i][j]=0;}for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i]==b[j-1]&&i>1)v[i][j]=j-1; else v[i][j]=v[i][j-1]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(a[i-1]==b[j]&&j>1)u[i][j]=i-1; else u[i][j]=u[i-1][j]; 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(v[i][j]!=0&&u[i][j]!=0&&a[i]!=b[j])    f[i][j]=max(f[i][j],f[u[i][j]-1][v[i][j]-1]+2); } cout<<f[n][m];return 0;}  


0 0
原创粉丝点击