博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1692 Crossed Matchings【DP】
阅读量:6871 次
发布时间:2019-06-26

本文共 2910 字,大约阅读时间需要 9 分钟。

Description

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

题目大意:就是找出相等的两个数连接起来,但是线段还要和一条匹配线段相交;

求最大的匹配数;

解题思路:f[i][j],表示i,j前的最大匹配数;

当a[i]==b[j]的时候,考虑到前i个数和j-1个数的最大匹配数,以及前i-1个数和j个数的最大匹配数;

当a[i]!=b[j]的时候,那么应该是max{f[p-1][q-1]+2}; 其中a[i]==b[q], b[j]==a[p], 且p<i, q<j;

那么程序的时间复杂度为:  O(m^2*n^2);

那么再找max{f[p-1][q-1]}的时候用了很多重复的操作,如果提前算出来时间复杂度会降为O(mn);

用二维数组max_a[i][j], 表示a[i]相等的b数组中前j(j<i)个数的最大匹配数的位置;

用二维数组max_b[i][j],表示b[i]相等的a数组中前j(j<i)个数的最大匹配数的位置;

 

#include
#include
#include
#include
#define N 103 using namespace std;int a[N], b[N], max_a[N][N], max_b[N][N], f[N][N]; int main(){ int i, T, n, m, j; scanf("%d", &T); while(T--) { memset(max_a, 0, sizeof(max_a)); memset(max_b, 0, sizeof(max_b)); memset(f, 0, sizeof(f)); scanf("%d%d", &n, &m); for(i=1; i<=n; i++) scanf("%d", &a[i]); for(i=1; i<=m; i++) scanf("%d", &b[i]); for(i=1; i<=n; i++) for(j=1; j<=m; j++) { if(a[i]==b[j-1]) max_a[i][j]=j-1; else max_a[i][j]=max_a[i][j-1]; } for(i=1; i<=m; i++) for(j=1; j<=n; j++) { if(b[i]==a[j-1]) max_b[i][j]=j-1; else max_b[i][j]=max_b[i][j-1]; } for(i=1; i<=n; i++) for(j=1; j<=m; j++) { f[i][j]=max(f[i][j-1], f[i-1][j]); int xx=max_a[i][j], yy=max_b[j][i]; if(xx>0&&yy>0&&f[yy-1][xx-1]+2>f[i][j]&&a[i]!=b[j]) f[i][j]=f[yy-1][xx-1]+2; } printf("%d\n", f[n][m]); }}

  

转载于:https://www.cnblogs.com/Hilda/archive/2012/10/11/2720470.html

你可能感兴趣的文章
全面总结: Golang 调用 C/C++,例子式教程
查看>>
安卓手机的屏幕规格很多。app开发者在设计User Interface的时候,要怎么处理,才能适应不同屏幕大小?...
查看>>
php合并数组并保留键值的方法
查看>>
WinEdit编辑器中中文乱码
查看>>
HTTP的长连接和短连接(转)
查看>>
《Java从入门到精通》第十三章学习笔记
查看>>
洛谷 p2530 化工场装箱员(资源型)
查看>>
js数组去重
查看>>
类职能的单一性
查看>>
java正则表达式实战例子,持续更新,记下来后面就不用重新写了。。。
查看>>
【玩转Golang】reflect.DeepEqual
查看>>
ssh免密码登录
查看>>
python ----Linux上安装scrapy
查看>>
Eclipse配置maven环境
查看>>
第五周PSP作业
查看>>
[转]Android 解析内存泄漏
查看>>
计算机组成原理(二)——计算机的基本组成
查看>>
Bellman-Ford&&SPFA
查看>>
Python轻量Web框架Flask使用
查看>>
用Supervisord管理Python进程
查看>>