zoukankan      html  css  js  c++  java
  • 江哥的DP题(B)

    【题目描述】

    给定两个1~N的序列A、B,如果Ai=Bj,则能够在Ai、Bj之间连一条直线,要求每条直线至多与一条直线相交。

    【输入描述】

    第一行输入一个正整数N;

    第二行输入N个正整数,表示序列A的元素;

    第三行输入N个正整数,表示序列B的元素。

    【输出描述】

    输出一个整数,表示最大的合法连线数量。

    【样例输入】

    7

    1 5 7 3 2 6 4

    7 3 4 1 6 5 2

    【样例输出】

    4

    【数据范围及提示】

    对于30%的数据,N ≤ 20; 
    对于100%的数据,N ≤ 1000。

    源代码:
    
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,i1[1001],i2[1001],j1[1001],j2[1001],f[1001][1001];
    int Max(int t1,int t2,int t3)
    {
        return max(max(t1,t2),t3);
    }
    int main()
    {
        scanf("%d",&n);
        for (int a=1;a<=n;a++)
        {
            scanf("%d",&i1[a]);
            j1[i1[a]]=a; //位置数组。 
        }
        for (int a=1;a<=n;a++)
        {
            scanf("%d",&i2[a]);
            j2[i2[a]]=a;
        }
        for (int a=1;a<=n;a++)
          for (int b=1;b<=n;b++)
            if (i1[a]==i2[b])
              f[a][b]=f[a-1][b-1]+1;
            else
            {
                f[a][b]=max(f[a][b-1],f[a-1][b]);
                if (j1[i2[b]]<a&&j2[i1[a]]<b)
                  f[a][b]=Max(f[j1[i2[b]]][j2[i1[a]]]+2,f[a-1][b],f[a][b-1]);
            }
        printf("%d",f[n][n]);
        return 0;
    }
    
    /*
        这个DP就厉害了。
        最近看多了厕厕的上树直播,所以说话一股摩登味,不要介意。
        设f[i][j]表示取序列A前i个元素与序列B前j个元素的最多连线数量,则有如下状态转移方程:
            (1)A[i]=B[j]
                f[i][j]=f[i-1][j-1]+1
            (2)A[i]≠B[j]
                f[i][j]=max(f[X][Y]+2,f[i-1][b],f[i][j-1])(X表示B[j]在序列A中的位置,Y与此同理)。
        此类型的DP似乎可以用前n项来二维实现。
    */
  • 相关阅读:
    博客第一篇:博客申请理由
    Cookie基础
    滚动篇————附一个简单单的自定义滚动条
    javascript中对字符串的操作总结
    javascript中创建对象的几种方式
    javascript中event汇总
    ...python scrapy
    Ubuntu 检测到系统出现问题 弹窗 嘿嘿
    万一哪天笔记全没了, 你真正记住的还有多少
    windows10安装mysql5.7.17是这样安装的吗?
  • 原文地址:https://www.cnblogs.com/Ackermann/p/6013808.html
Copyright © 2011-2022 走看看