[ACM_动态规划] UVA 12511 Virus [最长公共递增子序列 LCIS 动态规划]

简介:


 

 

  Virus 

We have a log file, which is a sequence of recorded events. Naturally, the timestamps are strictly increasing.

However, it is infected by a virus, so random records are inserted (but the order of original events is preserved). The backup log file is also infected, but since the virus is making changes randomly, the two logs are now different.

Given the two infected logs, your task is to find the longest possible original log file. Note that there might be duplicated timestamps in an infected log, but the original log file will not have duplicated timestamps.

 

Input 

The first line contains T (   T$ \le$100), the number of test cases. Each of the following lines contains two lines, describing the two logs in the same format. Each log starts with an integer n (   1$ \le$n$ \le$1000), the number of events in the log, which is followed by n positive integers not greater than 100,000, the timestamps of the events, in the same order as they appear in the log.   

 

Output 

For each test case, print the number of events in the longest possible original log file.   

 

Sample Input 

 

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

 

Sample Output 

 

3


题目大意:T种情况,每种情况2行数据,每行数据第一个表示个数,接下来是一个序列,问两组数据的最长公共递增子序列的长度。
解题思路:当看到这题想到的是LCS和LIS问题,没错这题也是动态规划问题,只要找到状态转移方程就可轻易搞定!
>_<:LIS设DP[i]表示以第i个数字结尾的最长上升子序列的长度
>0<:DP[i]=max(DP[j]+1){1<=j<=i-1}
   >_<:LCS设DP[i][j]表示以A串第i个字符结尾以B串第j个字符结尾的最长字串
>0<:当a[i]==b[j]时:DP[i][j]=DP{i-1][j-1]+1;
当a[i]!=b[j]时:DP[i][j]=max(DP[i-1][j],DP[i][j-1])
>_<:LCIS设F[i][j]表示以a串前i个字符b串的前j个字符且以b[j]为结尾构成的LCIS的长度
>0<:当a[i]!=b[j]时:F[i][j]=F[i-1][j]
当a[i]==b[j]时:F[i][j]=max(F[i-1][k])+1 1<=k<=j-1 && b[j]>b[k]
复制代码
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<string>
 4 #include<string.h>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<sstream>
 8 #include<iomanip>
 9 #include<algorithm>
10 #include<vector>
11 using namespace std;
12 int f[1005][1005],a[1005],b[1005],i,j,t,n1,n2,maxn; 
13 int main() 
14 { 
15     scanf("%d",&t); 
16     while(t--)
17     { 
18         scanf("%d",&n1); 
19         for(i=1;i<=n1;i++) scanf("%d",&a[i]); 
20         scanf("%d",&n2);
21         for(i=1;i<=n2;i++) scanf("%d",&b[i]); 
22         memset(f,0,sizeof(f)); 
23         for(i=1;i<=n1;i++) 
24         { 
25             maxn=0; 
26             for(j=1;j<=n2;j++) 
27             { 
28                 f[i][j]=f[i-1][j];//不相等
29                 if (a[i]>b[j]&&maxn<f[i-1][j]) maxn=f[i-1][j];//更新maxn
30                 if (a[i]==b[j]) f[i][j]=maxn+1;//相等
31             } 
32         } 
33         maxn=0; 
34         for(i=1;i<=n2;i++)if(maxn<f[n1][i])maxn=f[n1][i];
35         printf("%d\n",maxn);
36     }
37     return 0;
38 } 
复制代码

 

目录
打赏
0
0
0
0
23
分享
相关文章
|
10月前
leetcode-521:最长特殊序列 Ⅰ
leetcode-521:最长特殊序列 Ⅰ
60 0
|
9月前
|
力扣经典150题第二十六题:判断子序列
力扣经典150题第二十六题:判断子序列
39 0
|
10月前
【错题集-编程题】最长公共子序列(一)(动态规划 - LCS)
【错题集-编程题】最长公共子序列(一)(动态规划 - LCS)
|
10月前
【每日一题Day160】LC1092最短公共超序列 | 动态规划
【每日一题Day160】LC1092最短公共超序列 | 动态规划
67 0
【每日一题Day160】LC1092最短公共超序列 | 动态规划
《趣学算法-动态规划-最长的公共子序列》阅读笔记
《趣学算法-动态规划-最长的公共子序列》阅读笔记
130 0
《趣学算法-动态规划-最长的公共子序列》阅读笔记
【动态规划】最大子段和
输入一个整型数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。要求时间复杂度为O(n)。例如输入的数组为1,-2,3,10,-4,7,2,-5,和最大的子数组为3,10,-4,7,2,因此输出为该子数组的和18。
236 0
ACM模板——强连通分量(Tarjan)
ACM模板——强连通分量(Tarjan)
250 0
ACM模板——强连通分量(Tarjan)
ACM 选手玩转 LeetCode 滑动窗口解决长度最小的子数组
给定含有 n 个正整数的数组和一个正整数 target: 找出该数组中满足其和 ≥ target 的长度最小的连续子数组,并返回其长度,若不存在,返回 0。
ACM 选手玩转 LeetCode 滑动窗口解决长度最小的子数组
ACM知识 - 贪心算法和动态规划的区别与联系
ACM知识 - 贪心算法和动态规划的区别与联系
216 0
浙大版《C语言程序设计(第3版)》题目集 - 习题10-4 递归求简单交错幂级数的部分和(15 分)
浙大版《C语言程序设计(第3版)》题目集 - 习题10-4 递归求简单交错幂级数的部分和(15 分)
191 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等