• ZOJ 1425 Crossed Matchings(LCS变形)


    题目大意:

      就是说给你两行数字,然后对于每一行的相同的数字进行连线,每次连接成功后,就算是1次成功,求最大的成功次数。当然,要成功的话,也是要满足一定的条件的:

      1.在连接的过程中,不能用两根线连接了4个相同数字。

      2.一个数字不能发出两条线。

    解题思路:

      刚看到这个题,以为是图论的知识,感觉自己拿不下,,(有点像是什么二分图匹配吧,用两个颜色给相邻的顶点染色,求最多能有多少种这样的匹配,,逃)

    其实呢,这个有点像LCS,,,我第一次也没看出来,看了题解后,才明白的。

      我们规定这样的状态: dp[i][j] 表示第一行前i个数字和第二行前j个数字的最大匹配数目.

                由LCS的状态转移方程知道:dp[i][j] = max( dp[i-1][j],dp[i][j-1]);

      那么我们由题目要求的定义知道,如果出现第1行的第i个字符和第二行的第j个字符不同的时候,也就是说a[i]!=b[j],那么,我们开始先定住a[i],从b[j]开始往前找,如果找到了a[i]==b[k]的位置,那就说明,在a[i]和b[k]之间就会有一条连线了。这时候,由于一个元素只能发出一条连接,我们查找结束。

      接下来,我们定住b[j]按照同样的方法来在a[l]中去找,找到第一个a[l]==b[j]的地方,我们就结束掉。分别记录这两次查找的过程中a[l]==b[j]和a[i]==b[k]的l和k的位置,更新dp[i][j]用,因为但凡有了这两次连线,对于dp[i][j]来说就会贡献2条线。。。如果我们在两次查找的过程中,有某一次或者两次的l和k的位置都没有出现的话,我们就说明dp[i][j]并没有得到更新。

    代码:

     1 # include<cstdio>
     2 # include<iostream>
     3 # include<fstream>
     4 # include<algorithm>
     5 # include<functional>
     6 # include<cstring>
     7 # include<string>
     8 # include<cstdlib>
     9 # include<iomanip>
    10 # include<numeric>
    11 # include<cctype>
    12 # include<cmath>
    13 # include<ctime>
    14 # include<queue>
    15 # include<stack>
    16 # include<list>
    17 # include<set>
    18 # include<map>
    19 
    20 using namespace std;
    21 
    22 const double PI=4.0*atan(1.0);
    23 
    24 typedef long long LL;
    25 typedef unsigned long long ULL;
    26 
    27 # define inf 999999999
    28 # define MAX 123
    29 
    30 int a[MAX];
    31 int b[MAX];
    32 int dp[MAX][MAX];
    33 
    34 int main(void)
    35 {
    36     int t;cin>>t;
    37     while ( t-- )
    38     {
    39         int n,m;
    40         cin>>n>>m;
    41         for ( int i = 1;i <= n;i++ )
    42             cin>>a[i];
    43         for ( int i = 1;i <= m;i++ )
    44             cin>>b[i];
    45         int k,l;
    46         for ( int i =1;i<= n;i++ )
    47         {
    48             for ( int j = 1;j <= m;j++ )
    49             {
    50                 dp[i][j] = max( dp[i-1][j],dp[i][j-1] );
    51                 if ( a[i]!=b[j] )
    52                 {
    53                     for ( k = j-1;k >= 1;k-- )
    54                     {
    55                         if ( b[k]==a[i] )
    56                             break;
    57                     }
    58                     for ( l = i-1;l >= 1;l-- )
    59                     {
    60                         if ( a[l]==b[j] )
    61                             break;
    62                     }
    63 
    64                     if ( l!=0&&k!=0 )
    65                     {
    66                         dp[i][j] = max(dp[i][j],dp[l-1][k-1]+2 );
    67                     }
    68                 }
    69             }
    70         }
    71         cout<<dp[n][m]<<endl;
    72 
    73     }
    74 
    75 
    76     return 0;
    77 }
  • 相关阅读:
    Extjs 集合了1713个icon图标的CSS文件
    Sencha Touch 2 DataView / List 分页
    Sencha Touch 笔记
    [奉献]通过命令快速启动应用程序的小软件(QuickLauncher V1.1)
    PTC FlexPLM rfa 接口自动创建产品规格
    Excel Vba 调用WebService的两种方式,解决MSSOAP30 64位不兼容问题
    Extjs4.1.x 框架搭建 采用Application动态按需加载MVC各模块
    C#获取远程图片,需要Form用户名和密码的Authorization认证
    [转]plsql不安装oracle客户端 进行远程连接
    WPF、Silverlight程序编码资料收集
  • 原文地址:https://www.cnblogs.com/wikioibai/p/4405581.html
Copyright © 2020-2023  润新知