• 王子和公主 UVa10635


    【题目描述】:王子和公主

    一个王子和公主在n*n的格子中行走,这些格子是有1....n^2的编号的。现在给定p+1个数,再给定q+1个数,公主和王子可以选择其中某些格子行走,求他们最多能走几个相同的格子。

    【算法分析】:

    这道题读题是关键,然后我们发现需要的是公共的格子,又需要是这个步数最大化,可以想到最长公共子序列的模型。序列长度小于等于62500,最长公共子序列复杂度是n^2,超时。然而可以巧妙的将LCS转化为LIS,使用nlogn的方法求解

    解题思路:本题是一道经典的题目,巧妙的将LCS问题转化为LIS问题。这种题目的一个特定就是其中一个序列的所有元素均不相同。首先,我们可以对A数组重新编号为{1,2,3,...n},接下来对于B数组的每个元素,替换为A中那个元素的编号,若没有在A中出现,那么直接置0,这样,B数组也变为一个由编号构成的数组,此时我们发现,A数组是一个自然序列,那么只要在B中找到最长上升的子序列,就是和A的最长公共子序列!这就是本题的巧妙之处!而LIS问题有O(N*logN)的解法,因此可以通过本题的数据规模。

    为什么呢?

    A'中为A中元素的代号 即 它们的顺序号

    B'中为B中元素对应的代号(为了分析方便,这里将B中有而A中没有出现的去掉,等价于置0)

    因为去掉了B中有而A中没有出现的,所以B'中的代号全部对应A中的数

    设B'的一个子集p,那么将p由代号翻译成原来数字后一定是A的一个子集(不过在A中顺序不确定)

    B'的LIS时B‘中一个上升的子集 即 顺序号上升的子集 即 该子集在A中是按从左到右的顺序的

    所以它是A与B的公共子序列

    又因为LIS最长,所以公共子序列最长 即 最长公共子序列

    #include<iostream>
    #include<cstring>
    #define Max_n 300
    using namespace std;
    
    int a[Max_n*Max_n],b[Max_n*Max_n];
    int f[Max_n*Max_n];
    int n,p,q;
    int lable[Max_n*Max_n];
    
    int LIS(){
        f[1]=1;
        int num=0;
        for(int i=2;i<=q+1;i++){
            for(int j=1;j<i;j++) if(b[j]<b[i]){
                f[i]=max(f[i],f[j]+1);
            }
            num=max(num,f[i]);
            //cout<<i<<':'<<f[i]<<endl;
        }
        return num;
    }
    
    int main(){
        memset(lable,0,sizeof(lable));
        freopen("27.in","r",stdin);
        
        int x;
        cin>>n>>p>>q;
        for(int i=1;i<=p+1;i++){
            cin>>x;
            if(lable[x]==0){
                lable[x]=i;
            }
            a[i]=lable[x];
            //cout<<a[i]<<' ';
        }
        //cout<<endl;
        for(int i=1;i<=q+1;i++){
            cin>>x;
            b[i]=lable[x];
            //cout<<b[i]<<' ';
        }
        //cout<<endl;
        
        int ans=LIS();
        
        cout<<ans;
        
        fclose(stdin);
        return 0;
    } 
  • 相关阅读:
    轻重搭配
    EF的优缺点
    使用bootstrap-select有时显示“Nothing selected”
    IIS发布 HTTP 错误 500.21
    js添加的元素无法触发click事件
    sql server查看表是否死锁
    sql server把一个库表的某个字段更新到另一张表的相同字段
    SQLSERVER排查CPU占用高的情况
    SQL server中如何按照某一字段中的分割符将记录拆成多条
    LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.
  • 原文地址:https://www.cnblogs.com/FuTaimeng/p/5410465.html
Copyright © 2020-2023  润新知