zoj1425Crossed Matchings

哇哇哇哇。。又A了一道。。

刚写出来的,感觉好激动。。

下午的时候看了下题目,题目大意为两行数字,上下相同的数字连线算一次匹配,求可能的最大匹配,规则是:I 连线必须且只能被另一条直线穿过。且这两条直线代表的数字不能相同。II 一个数字只能有一条连线。

刚开始没什么想法,也有想到dp,不过没想到具体怎么实现。。

晚上又仔细看了下,感觉dp应该可以做出来,用了好多for循环,不过如果按我的思路来理解会很简单的。。

dp[i][j]表示第一行数字从第i个到n,第二行数字从第j个到m,这么些数字有多少个匹配。

对于dp[i][j-1],只需要讨论b[j-1]与第一行的a[i]...a[n]的匹配情况。。

看代码:

# include<stdio.h>

# include<string.h>

int a[105],b[105],n,m,dp[105][105];

int main()

{

	int i,j,t,k,h,s,flag,max;

	scanf("%d",&t);

	while(t--)

	{

		scanf("%d%d",&n,&m);

		for(i=1;i<=n;i++)

			scanf("%d",&a[i]);

		for(j=1;j<=m;j++)

			scanf("%d",&b[j]);

		for(j=1;j<=m;j++)

		{

			dp[n][j]=0;

			dp[n+1][j]=0;

		}

		for(i=1;i<=n;i++)

		{

			dp[i][m]=0;

			dp[i][m+1]=0;

		}

		dp[n+1][m+1]=0;/*特别注意,刚开始就是少加了这句话而wa了好几次*/

		for(i=n-1;i>=1;i--)

			for(j=m-1;j>=1;j--)

			{

				max=dp[i][j+1];/*初始化为没有与b[j]匹配的情况*/

				for(k=i+1;k<=n;k++)

				{

					if(b[j]==a[k]) 

					{

						flag=0;

						for(h=j+1;h<=m;h++)

						{

							if(b[h]==b[j]) continue;/*两个连线 的数字不能相等*/

							for(s=i;s<k;s++)

							{

								if(b[h]==a[s]) {flag=1;break;}

							}

							if(flag==1) break;

						}

						if(flag==1) 

						{

							if(max<dp[k+1][h+1]+2) max=dp[k+1][h+1]+2;/*如果找到一组匹配*/

						}

					}

				}

				dp[i][j]=max;

			}

			printf("%d\n",dp[1][1]);

	}

	return 0;

}

你可能感兴趣的:(match)