CSU 1120 病毒(经典模板例题:最长公共递增子序列)

1120: 病毒

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 390  Solved: 153
[Submit][Status][Web Board]

Description

你有一个日志文件,里面记录着各种系统事件的详细信息。自然的,事件的时间戳按照严格递增顺序排列(不会有两个事件在完全相同的时刻发生)。

遗憾的是,你的系统被病毒感染了,日志文件中混入了病毒生成的随机伪事件(但真实事件的相对顺序保持不变)。备份的日志文件也被感染了,但由于病毒采用的随机感染方法,主日志文件和备份日志文件在感染后可能会变得不一样。

给出被感染的主日志和备份日志,求真实事件序列的最长可能长度。

Input

输入第一行为数据组数T (T<=100)。每组数据包含两行,分别描述感染后的主日志和备份日志。

每个日志文件的格式相同,均为一个整数n (1<=n<=1000)(代表感染后的事件总数)和n 个不超过100,000的正整数(表示感染后各事件的时间戳)。

注意,感染后可能会出现时间戳完全相同的事件。

Output

对于每组数据,输出真实事件序列的最长可能长度。

Sample Input

1
9 1 4 2 6 3 8 5 9 1
6 2 7 6 3 5 1

Sample Output

3
相比之前做的单调递增、最长公共子序列,这题将两者结合,很经典的一道例题。
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn=1005;
 7 int dp[maxn],a[maxn],b[maxn],n,m;
 8 int LICS()
 9 {
10     int i,j,MAX;
11     memset(dp,0,sizeof(dp));
12     for(i=1;i<=n;i++)
13     {
14         MAX=0;
15         for(j=1;j<=m;j++)
16         {
17             if(a[i]>b[j] && MAX<dp[j])
18                 MAX = dp[j];
19             if(a[i]==b[j])
20                 dp[j]=MAX+1;
21         }
22     }
23     MAX=0;
24     for(i=1;i<=m;i++)
25         if(MAX<dp[i])
26             MAX=dp[i];
27     return MAX;
28 }
29
30 int main()
31 {
32     int T,i;
33     scanf("%d",&T);
34     while(T--)
35     {
36         scanf("%d",&n);
37         for(i = 1;i<=n;i++)
38         scanf("%d",&a[i]);
39         scanf("%d",&m);
40         for(i = 1;i<=m;i++)
41         scanf("%d",&b[i]);
42         printf("%d\n",LICS());
43     }
44     return 0;
45 }
时间: 2024-11-11 05:32:36

CSU 1120 病毒(经典模板例题:最长公共递增子序列)的相关文章

HDU ACM 4512 吉哥系列故事——完美队形I -&gt;LCIS最长公共递增子序列

分析:最长公共递增子序列,把数据反向存储一遍,求正反两组数据的LCIS.另外注意边界的条件判断.还有如果取出的新队列有奇数个人或偶数个人要单独判断. #include<iostream> using namespace std; #define max(a,b) ((a)>(b)?(a):(b)) int dp[202]; int a[202]; int b[202]; int LCIS(int n) { int i,j,maxlen,ans; memset(dp,0,sizeof(dp

模板 最长公共递增子序列

[模板]最长递增公共子序列 二维 1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 using namespace std; 5 6 int n,m,a[505],b[505],dp[505][505]; 7 8 int LICS() 9 { 10 int MAX,i,j; 11 memset(dp,0,sizeof(dp)); 12 for(i = 1; i<=n; i++)

最长公共递增子序列【模板】

虽然很多人说记模板提升空间有限,但是对于我这种菜鸟级别的人来说.能做的也只有记记模板了! 希望这个模板能帮到你,如果有更好的模板记得告诉我哦!!谢谢. 二维代码: #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int n,m,a[505],b[505],dp[505][505]; int LICS() { int max,i,j; memset(dp,0,siz

CSU 1120 病毒

最长公共上升子序列(LCIS) 裸的算法题,没什么好说的. ps:找这个算法的时候看到某队省赛的时候不会,同病相怜哈,还好我们只是训练赛不会.灭哈哈哈~ 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 int f[1005][1005]; 7 int main (){//cout<<"error"<&l

UVA 12511/CSU 1120 virus 最长公共上升子序列

第一次接触一个这最长公共上升子序列 不过其实搞清楚了跟最长公共子序列和 最长上升子序列如出一辙 两重循环,对于当前不相等的,等于前一个的值,相等的,等于比当前A[i]小的最大值+1.弄个临时变量记录最大值即可 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int dp[2][1010]; int A[1010

【luogu1439】 【模板】最长公共子序列 [动态规划][LIS最长上升子序列][离散化]

P1439 [模板]最长公共子序列 此思路详见luogu第一个题解 一个很妙的离散化 刘汝佳蓝书上面的LIS 详见蓝书 d[i]以i为结尾的最长上升子序列的长度     g[i]表示d值为i的最小状态的编号即长度为i的上升子序列的最小末尾值 1 for(int i=1;i<=n;++i) scanf("%d",&a[i]); 2 for(int i=1;i<=n;++i) 3 { 4 int k=lower_bound(g+1,g+1+n,a[i])-g; 5 d[

最长公共上升子序列(LCIS)问题的O(n^2)解法

J - 病毒 Time Limit:3000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit Status Practice CSU 1120 Appoint description:  System Crawler  (2015-01-04) Description 你有一个日志文件,里面记录着各种系统事件的详细信息.自然的,事件的时间戳按照严格递增顺序排列(不会有两个事件在完全相同的时刻发生). 遗憾的是,

HDU 4512 最长公共上升子序列

各种序列复习: (1)最长上升子序列. 1.这个问题用动态规划就很好解决了,设dp[i]是以第i个数字结尾的上升子序列的最长长度.那么方程可以是dp[i]=max(dp[j]+1).(j<i).复杂度为O(n^2); 2.另外有一个该经典问题的O(nlogn)算法. 首先知道,当求dp[i]时,如果出现a[k]<a[j],而dp[k]=dp[j]时,应当优先选k吧.那么,既然每次选的都是较小,就可以把字符串按照dp[t]=k这个子序列长度分类.当同样dp[t]=k时,记录下该长度的最小的a[p

[codevs2185]最长公共上升子序列

试题描述 熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们要研究最长公共上升子序列了.小沐沐说,对于两个串A,B,如果它们都包含一段位置不一定连续的数字,且数字是严格递增的,那么称这一段数字是两个串的公共上升子串,而所有的公共上升子串中最长的就是最长公共上升子串了.奶牛半懂不懂,小沐沐要你来告诉奶牛什么是最长公共上升子串.不过,只要告诉奶牛它的长度就可以了. 输入 第一行N,表示A,B的长度.第二行,串A.第三行,串B.