贼有意思[最长上升公共子序列](SAC大佬测试题)

题目描述
Awson 最近越来越蠢了,一天就只知道 zyys。
他定义了一个 zyys 数列:这个数列满足:
1.是另外两个数列 A,B 的公共子序列;
2.数列单调递增。
现在他有一个问题,我们假设知道两个长度均为 N 的序列 A,B,如何去找最长的 zyys
数列呢?由于他只会 zyys 了,他把这个问题交给了你。
输入格式
第一行包含一个整数 N,表示序列 A,B 的长度;
接下来 2 行,每行 N 个数,表示序列 A,B。
输出格式
一行,输出最长的 zyys 数列。
输入样例
5
2 3 3 3 4
2 3 3 4 5
输出样例
3
数据范围
对于 50%的数据,有 N <= 50
对于 100%的数据,有 N <= 5000

50分:

f[i][j]=f[i'][j']  (a[i]==b[j],a[i']<a[i],a[i']==b[j'],i'<i,j'<j)

复杂度为O(n^4)

100分,只要稍作修改

我们令 f[i][j]表示A[1~i]以 B[j]为最后该序列的最后一个数的最长长度。

如果a[i]==b[j]则f[i][j]=maxlen(f[i-1][j'])+1   (a[i]>b[j'],j'<j)

否则显然f[i][j]=f[i-1][j]

maxlen那一部分边循环边更新就行了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 int n;
 7 int a[5001],b[5001];
 8 int f[5001][5001],ans;
 9 int main()
10 {
11     int i,j,k,l;
12     cin>>n;
13     for (i=1; i<=n; i++)
14     {
15         scanf("%d",&a[i]);
16     }
17     for (i=1; i<=n; i++)
18     {
19         scanf("%d",&b[i]);
20     }
21     for (i=1; i<=n; i++)
22     {
23         int len=0;
24         for (j=1; j<=n; j++)
25         {
26             if (a[i]==b[j]) f[i][j]=len+1;
27             else f[i][j]=f[i-1][j];
28             if (a[i]>b[j]&&f[i-1][j]>len) len=f[i-1][j];
29             ans=max(ans,f[i][j]);
30         }    
31     }
32 cout<<ans;
33 }

 

posted @ 2017-09-18 16:23  Z-Y-Y-S  阅读(338)  评论(0编辑  收藏  举报