王子和公主 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;
} 
时间: 2024-07-30 10:12:45

王子和公主 UVa10635的相关文章

uva10635 王子和公主(把lcs转化为lis)

有两个长度为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n*n之间的整数,两个序列的第一个元素都是1,求a和b的最长公共子序列的长度. 思路很容易想到lcs,但是由于O(pq)的算法肯定会超时,所以不能采用,注意到a和b中的元素互不相同,故可以预处理a中的元素,用trans数组记录a每个元素值对应的位置,然后处理b中的元素,把每个元素转化成该元素在a中的位置,如果没在a中出现那么为零,这样就把lcs问题转化成了lis #include<cstdio> #include<

动态规划 最长公共子序列 王子和公主 Prince and Princess UVa 10635

#include <iostream> #include <algorithm> using namespace std; const int maxn = 250 * 250; int main(){ char T; cin >> T; for (char k = 0; k < T;k++) { int n, p, q; cin >> n >> p >> q; int num[maxn]; memset(num, 0, siz

王子和公主的童话

http://club.jd.com/CommunityGroupDetail/25094575_1.html http://club.jd.com/CommunityGroupDetail/25094786_1.html http://club.jd.com/CommunityGroupDetail/25094864_1.html http://club.jd.com/CommunityGroupDetail/25094733_1.html http://club.jd.com/Communi

王子和公主

题意简化一下,这道题还是比较不错的,虽然我还没有实现过,不过我是已经理解了. 题意:有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1-n^2之间的整数,两个序列的第一个元素均为1,求A和B的最长公共子序列的长度. T<=10 2<=N<=250 这道题是一道LCS的题,但是最快的LCS的速度也为O(pq)62500^2这个是过不了的,所以从题目的特殊性考虑如何解这道题,发现序列中的各个元素互不相同,这有什么用呢? 可以将它重新标号,如A={1,7,5,4,8,

[转]王垠的过去和现状

王垠的过去和现状 我曾在2006年冬季接触到王垠的三篇文章:<完全用linux工作>.<写给支持和反对<完全用Linux工作>的人们>.<清华梦的粉碎--写给清华大学的退学申请>,今天巧合又再次读遍,于是决定把我知道关于王垠的信息总结一下. 1. 从清华退学 王垠是高考发挥失常进入四川大学计算机系97级(据此推测他是79.80生人):2001年直接保送到清华大学计算机系软件所硕博连读,主要进行集成电路布线算法的研究. 2004年8月左右[1],王垠完成了&l

UVA10635 Prince and Princess(LIS)

题意:王子和公主同时从1出发走到 n*n, 求他们两个路径的最长公共子序列: 思路:因为这题n有250,如果用LCS负责度为O(n^2),容易超时,于是我们选择它的优化版Lis算法来求最长公共子序列,这样我们的复杂度就降为O(n*logn)了. Lis算法: 先回顾经典的O(n^2)的动态规划算法,设A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设F[t] = 0(t = 1, 2, ..., len(A)).则有动态规划方程:F[t] = ma

聚焦新相亲时代:女孩在京有五六套房哭着想嫁富2代

2017-09-20 07:31:00 来源: 中国青年报(北京)        举报 6984 分享到: 易信 微信 QQ空间 微博 更多 用微信扫码二维码 分享至好友和朋友圈 T + - (原标题:中青报聚焦新相亲时代:2亿人及其背后家庭组成的"擂台") 石家庄某相亲角.视觉中国 资料 平均算下来,每一分钟里,国内有22对新人拿着户口本走向民政局,进入婚姻生活:同时,8对夫妻在另外一个窗口签下离婚协议. 根据民政部公布的数字,中国的结婚率和离婚率曲线渐渐逼近一个闭合的大于号.婚姻的

程序员到项目经理:从内而外的提升

转自:http://www.cnblogs.com/watsonyin/archive/2012/09/10/2679528.html 目录 从程序员到项目经理(一):为什么要当项目经理 从程序员到项目经理(二):升职之辨 从程序员到项目经理(三):认识项目经理 从程序员到项目经理(四):外行可以领导内行吗 从程序员到项目经理(五):程序员加油站,不是人人都懂的学习要点 从程序员到项目经理(六):程序员加油站 — 懂电脑更要懂人脑 从程序员到项目经理(七):程序员加油站 — 完美主义也是一种错

/异常语句try,catch.

//try//保护执行里面的代码段,若其中一句错误,直接跳转到catch,不会管下面的内容 //{ // Console.WriteLine("请输入一个整数"); // int a = int.Parse(Console.ReadLine()); // Console.WriteLine("hello"); // break; //} //catch// //{ // Console.WriteLine("您的输入有误"); //} //Con