Crossed Matchings——动态规划

来源:互联网 发布:java基础入门txt下载 编辑:程序博客网 时间:2024/04/24 06:32
There are two rows of positive integer numbers. We can draw one line segment between any two equal numbers, with values r, if one of them is located in the first row and the other one is located in the second row. We call this line segment an r-matching segment. The following figure shows a 3-matching and a 2-matching segment.


We want to find the maximum number of matching segments possible to draw for the given input, such that:
1. Each a-matching segment should cross exactly one b-matching segment, where a != b .
2. No two matching segments can be drawn from a number. For example, the following matchings are not allowed.


Write a program to compute the maximum number of matching segments for the input data.Note that this number is always even.
Input
The first line of the input is the number M, which is the number of test cases (1 <= M <= 10). Each test case has three lines. The first line contains N1 and N2, the number of integers on the first and the second row respectively. The next line contains N1 integers which are the numbers on the first row. The third line contains N2 integers which are the numbers on the second row. All numbers are positive integers less than 100.


Output

Output should have one separate line for each test case. The maximum number of matching segments for each test case should be written in one separate line.


Sample Input

3
6 6
1 3 1 3 1 3
3 1 3 1 3 1
4 4
1 1 3 3
1 1 3 3
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
Sample Output

6

0

8


题意:给了两个串(a,b),求两个串的最大匹配数。

匹配规则(我自己理解的):

1.两个相同的数才能匹配(在这两个数之间连一条线)

2.每个匹配还要有另一个匹配与之相交,并且这两个匹配的数字不同(这一条决定了最大匹配数一定是个偶数)

3.每个数只能匹配一次


想法:

定义一个dp[i][j],代表从a串里取前i个,从b里面取前j个相匹配的最大匹配值。

然后分别从aa(从a里面取出的串)末尾往前找是否有和bb(同aa)末尾相同的数字,之后在从bb末尾进行相同操作

如果都找到了则一定满足匹配规则,那么dp[i][j]=max(dp[i][j], dp[i-1][j-1]+2)

但是要注意aa和bb末尾的数字不能相同,如果相同也不满足匹配规则2,无法匹配

如果没找到,那么dp[i][j]=max(dp[i-1][j], dp[i][j-1])

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int len1, len2;int a[105],b[105], dp[105][105];int main(){    int t;    scanf("%d", &t);    while(t--)    {        scanf("%d%d", &len1, &len2);        for(int i=1; i<=len1; i++)            scanf("%d",&a[i]);        for(int i=1; i<=len2; i++)            scanf("%d", &b[i]);        memset(dp, 0, sizeof(dp));        for(int i=1; i<=len1; i++)            for(int j=1; j<=len2; j++)            {                dp[i][j]=max(dp[i-1][j], dp[i][j-1]);   //没找到的情况                if(a[i]!=b[j])               //末尾不相同                {                    int ii=0, jj=0;                    for(ii=i-1; ii>0; ii--)                        if(a[ii]==b[j])                            break;                    for(jj=j-1; jj>0; jj--)                        if(a[i]==b[jj])                            break;                    if(ii&&jj)           //如果都找到了                        dp[i][j]=max(dp[i][j], dp[ii-1][jj-1]+2);                }            }        printf("%d\n", dp[len1][len2]);    }    return 0;}