码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-09-18 17:18:27      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:cst   code   div   ++   数据   style   stream   namespace   color   

题目描述
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 }

 

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

标签:cst   code   div   ++   数据   style   stream   namespace   color   

原文地址:http://www.cnblogs.com/Y-E-T-I/p/7543708.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!