POJ1692————Crossed Matchings(动态规划)

来源:互联网 发布:童谣诈骗 知乎 编辑:程序博客网 时间:2024/04/25 21:21

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
36 61 3 1 3 1 33 1 3 1 3 14 41 1 3 3 1 1 3 3 12 111 2 3 3 2 4 1 5 1 3 5 103 1 2 3 2 4 12 1 5 5 3 
Sample Output
608


两组数,如果上面那组有个数r,同时下面也有数r,就可以把两组数连起来,称作一个r匹配。

对于每一个a匹配,必须要有恰好一个b匹配与之相交,并且a不等于b。

两个匹配不能共用一个数字。

dp[i][j]表示A组前i个和B组前j个的最大匹配。以下开始分类讨论

如果a[I]=b[j],那么匹配数不会增加,因为不会有其他匹配与之相交。

如果不等,那么就可以在A组和B组之前的数字中去找,如果有刚好分别和最后两个数相等的,就可以增加匹配。

具体的看代码吧。




#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>using namespace std;const int MAXN=110;int x[MAXN],y[MAXN];int dp[MAXN][MAXN];int main(int argc, char *argv[]) {    int t;    scanf("%d",&t);    while(t--){        int n,m;        scanf("%d%d",&n,&m);        memset(dp,0,sizeof(dp));        for(int i=1;i<=n;i++)            scanf("%d",x+i);        for(int i=1;i<=m;i++)            scanf("%d",y+i);        dp[0][0]=0;        for(int i=1;i<=n;i++){            for(int j=1;j<=m;j++){                dp[i][j]=max(dp[i][j],max(dp[i-1][j],dp[i][j-1]));                if(x[i]==y[j])                    continue;                int flag=1;                for(int p=i-1;p>=1&&flag;p--){                    for(int q=j-1;q>=1;q--){                        if(x[p]==y[j]&&x[i]==y[q]){                            dp[i][j]=max(dp[i][j],dp[p-1][q-1]+2);                            flag=0;                            break;                        }                    }                }            }        }        printf("%d\n",dp[n][m]);    }}








0 0
原创粉丝点击