LCIS

传送门

http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=726&pid=1003

分析:这道题依然是动态规划,实际上是经典问题的变形,因为要求值必须连续,所以我们应该采取一些特殊的手段。

    我们设f[i]表示f[i]为第一个序列中以高度i为结尾的最长连续递增子序列,使用g[i] 表示第二个序列的所以每读入一个数

    所以我们有f[i] = f[i-1] + 1;g[i]类似

然后我们考虑统计答案,易得,ans = max{min{f[i],g[i]}}

因为要求的是公共子序列,所以不能选择两个序列中长的那个,也就是说,我们一定有较短的序列出现在另一个序列中。

    所以我们就可以统计答案了。

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 inline void read(int &x){
 9     x=0;char ch;bool flag = false;
10     while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
11     while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
12 }
13 inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
14 inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
15 const int maxn = 100010;
16 const int maxnum = 2000010;
17 int f[maxnum],g[maxnum];
18 int a[maxn],b[maxn];
19 int main(){
20     int T;read(T);
21     while(T--){
22         int n,m;read(n);read(m);
23         for(int i=1;i<=n;++i){
24             read(a[i]);
25             f[a[i]] = f[a[i]-1] + 1;
26         }int ans = 0;
27         for(int i=1;i<=m;++i){
28             read(b[i]);
29             g[b[i]] = g[b[i]-1] + 1;
30             ans = cat_max(ans,cat_min(f[b[i]],g[b[i]]));
31         }printf("%d\n",ans);
32         for(int i=1;i<=n;++i) f[a[i]] = 0;
33         for(int i=1;i<=m;++i) g[b[i]] = 0;
34     }
35     getchar();getchar();
36     return 0;
37 }

 

posted @ 2016-11-02 06:28  Sky_miner  阅读(269)  评论(0编辑  收藏  举报