哇哇哇哇。。又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;
}
浙公网安备 33010602011771号