哇哇哇哇。。又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;
}
posted on 2011-04-07 21:58  奋斗青春  阅读(246)  评论(0编辑  收藏  举报