COGS 597 交錯匹配 題解

【問題描述】
    有兩行自然數, 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.in
12 11
1 2 3 3 2 4 1 5 1 3 5 10
3 1 2 3 2 4 12 1 5 5 3

輸出:

crossa.out
8

【輸入輸出樣例2】 
輸入:

crossa.in
4 4
1 1 3 3
1 1 3 3

輸出:

crossa.out
0

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



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;
}  


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章