zoj1425 Crossed Matchings
2014-06-07 22:35
239 查看
【题意】:给你上下各一列数,让你进行匹配。规则是数字相同的才可以匹配,且每个数字只可以被匹配一次,并且匹配的时候一定要是两个匹配以线段相交的形式出现,且每组匹配只能有一个交点。再然后,还有一个限制条件,就是每组两个匹配的四个字符不能都是一样的。示意图戳开链接看。
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1425
【分析】:这道题看起来有点像最长公共子序列。因为给的序列是两个线性的。所以,我们考察dpi][j]的状态。
首先dp[i][j]分别表示串1和2分别处理到i和j位置是,能够得到的最大的匹配数。很不错的题目
我们考虑dp问题的时候一定要考虑状态转移!!!!!
当s1[i]和s2[j]失配的时候,那么一定是s1[i]和s2[1]----s2[j-1]的这些字符可能存在匹配,即dp[i][j-1]
同样,s2[j]和s1[1]----s1[i-1]可能存在匹配,假设找到p2,即dp[i-1][j]
那么,当s1[i]向前找到匹配的s2[p1],且当s2[j]向前找到匹配的s1[p2]时,且s1[i]!=s2[j]时,一定又找到了一对新的交叉线。
所以://s1[i]!=s2[j]
dp[i][j]=max(dp[i][j],dp[i-1][j]);
dp[i][j]=max(dp[i][j],dp[i][j-1]);
if(mati>0 && matj>0) dp[i][j]=max(dp[i][j],dp[matj-1][mati-1]+2);
那么s1[i]==s2[j]时,若两点形成一条线,那么要找到交叉线一定是一个在[i,j]区间左,一个在右,那么不可能形成新的匹配。
所以dp[i][j]=max(dp[i-1][j],dp[i][j-1]) 具体看代码
【代码】:
View Code
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1425
【分析】:这道题看起来有点像最长公共子序列。因为给的序列是两个线性的。所以,我们考察dpi][j]的状态。
首先dp[i][j]分别表示串1和2分别处理到i和j位置是,能够得到的最大的匹配数。很不错的题目
我们考虑dp问题的时候一定要考虑状态转移!!!!!
当s1[i]和s2[j]失配的时候,那么一定是s1[i]和s2[1]----s2[j-1]的这些字符可能存在匹配,即dp[i][j-1]
同样,s2[j]和s1[1]----s1[i-1]可能存在匹配,假设找到p2,即dp[i-1][j]
那么,当s1[i]向前找到匹配的s2[p1],且当s2[j]向前找到匹配的s1[p2]时,且s1[i]!=s2[j]时,一定又找到了一对新的交叉线。
所以://s1[i]!=s2[j]
dp[i][j]=max(dp[i][j],dp[i-1][j]);
dp[i][j]=max(dp[i][j],dp[i][j-1]);
if(mati>0 && matj>0) dp[i][j]=max(dp[i][j],dp[matj-1][mati-1]+2);
那么s1[i]==s2[j]时,若两点形成一条线,那么要找到交叉线一定是一个在[i,j]区间左,一个在右,那么不可能形成新的匹配。
所以dp[i][j]=max(dp[i-1][j],dp[i][j-1]) 具体看代码
【代码】:
#include <iostream> #include <string.h> #include <stdio.h> using namespace std; int dp[105][105]; int N1,N2; int a[105],b[105]; int main(){ int M; scanf("%d",&M); while(M--){ scanf("%d%d",&N1,&N2); for(int i=1;i<=N1;i++) scanf("%d",&a[i]); for(int i=1;i<=N2;i++) scanf("%d",&b[i]); memset(dp,0,sizeof(dp)); for(int i=1;i<=N1;i++){ for(int j=1;j<=N2;j++){ if (a[i]==b[j]) dp[i][j]=max(dp[i-1][j],dp[i][j-1]); if (a[i]!=b[j]) { int mati=-1,matj=-1; for(int p=j-1;p>=1;p--){//在第二行搜索可能匹配的位置 if (b[p]==a[i]) { mati=p;break; } } for(int p=i-1;p>=1;p--){//在第一行搜索匹配b的位置 if (a[p]==b[j]){ matj=p;break; } } dp[i][j]=max(dp[i][j],dp[i-1][j]); dp[i][j]=max(dp[i][j],dp[i][j-1]); if(mati>0 && matj>0) dp[i][j]=max(dp[i][j],dp[matj-1][mati-1]+2); } } } cout<<dp[N1][N2]<<endl; } return 0; }
View Code
相关文章推荐
- zoj 1425 Crossed Matchings
- ZOJ1425 Crossed Matchings dp
- zoj1425Crossed Matchings
- ZOJ_Crossed Matchings DP
- zoj 1425 最大交叉匹配
- 【POJ】1692 Crossed Matchings
- POJ 1692 Crossed Matchings
- Crossed Matchings——动态规划
- POJ1692 Crossed Matchings
- ZOJ 1425 Crossed Matchings(LCS变形)
- ZOJ1425 POJ1692 Crossed Matchings
- [ACM_动态规划] ZOJ 1425 Crossed Matchings(交叉最大匹配 动态规划)
- PKU1692 Crossed Matchings
- zoj 1425 最多匹配交叉 LCS
- poj 1692 Crossed Matchings
- POJ1692 Crossed Matchings DP
- POJ1692 Crossed Matchings
- ZOJ 1425 Crossed Matchings(动态规划)
- POJ1692 Crossed Matchings
- POJ 1692 Crossed Matchings