zoukankan      html  css  js  c++  java
  • JZOJ 4.2 C组 交错匹配【dp】

    题目描述

    有两行自然数,UP[1..N],DOWN[1..M],如果UP[I]=DOWN[J]=K,那么上行的第I个位置的数就可以跟下行的第J个位置的数连一条线,称为一条K匹配,但是同一个位置的数最多只能连一条线。另外,每个K匹配都必须且至多跟一个L匹配相交且K≠L!现在要求一个最大的匹配数。

    例如:以下两行数的最大匹配数为8
    这里写图片描述

    输入

    从文件CROSS. in读入数据,第一行有两个正整数N和M。第二行N个UP的自然数,第三行M个DOWN的自然数。其中0< N、M<=200,UP、DOWN的数都不超过32767。

    输出

    最大匹配数输出到CROSS.OUT。

    样例输入

    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

    样例输出

    8


    简单的dp题
    设f[i,j]第一个序列的前i个和第二序列的前j个最多能匹配数。
    现将f[i,j]赋值为max([f[i-1,j],f[i,j-1])
    然后我们判断到当前能不能匹配更多的数,如果可以将f[i,j]更新(tips:每次就是匹配两个,所以每次f[i,j]+2


    代码如下:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int a[205]={0},b[205]={0},f[205][205]={0},n,m,la,lb;
    
    void get(int i,int j)
    {
        int x=a[i],y=b[j];
        la=i-1;
        lb=j-1;
        while(a[la]!=y && la>0)la--;
        while(b[lb]!=x && lb>0)lb--;
    }
    
    int main()
    {
        freopen("cross.in","r",stdin);
        freopen("cross.out","w",stdout);
        int i,j,k,t;
        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++)
            {
                f[i][j]=max(f[i-1][j],f[i][j-1]);
                get(i,j);
                if(la!=0 && lb!=0 && a[la]!=b[lb]) if(f[la-1][lb-1]+2>f[i][j]) f[i][j]=f[la-1][lb-1]+2;
            }   
        printf("%d",f[n][m]);
        return 0;
    }
  • 相关阅读:
    1046 Shortest Distance (20 分)(模拟)
    1004. Counting Leaves (30)PAT甲级真题(bfs,dfs,树的遍历,层序遍历)
    1041 Be Unique (20 分)(hash散列)
    1036 Boys vs Girls (25 分)(查找元素)
    1035 Password (20 分)(字符串处理)
    1044 Shopping in Mars (25 分)(二分查找)
    onenote使用小Tip总结^_^(不断更新中...)
    1048 Find Coins (25 分)(hash)
    三个故事
    领导者的举止
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8412336.html
Copyright © 2011-2022 走看看