code 2185 最长公共上升子序列 (dp)

来源:互联网 发布:淘宝怎么下载数据包 编辑:程序博客网 时间:2024/05/22 09:45

2185 最长公共上升子序列

 时间限制: 1 s
 空间限制: 32000 KB
 题目等级 : 钻石 Diamond
题目描述 Description

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

输入描述 Input Description

第一行N,表示A,B的长度。
第二行,串A。
第三行,串B。

输出描述 Output Description

输出长度。

样例输入 Sample Input

4
2 2 1 3
2 1 2 3

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

1<=N<=3000,A,B中的数字不超过maxlongint


题解:dp

f[i][j]表示a的前i个和b的前j个严格以a[i]结尾的最长公共上升子序列的长度。

分两种情况进行讨论:

a[i]=b[j]  枚举k,保证a[k]<a[i]  f[i][j]=max(f[i][j],f[k][j-1]+1)

a[i]!=b[j]  f[i][j]=f[i][j-1]

O(n^3)  dp

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define N 3003using namespace std;int n,m,f[N][N],a[N],b[N];int main(){scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]);for (int i=1;i<=n;i++) scanf("%d",&b[i]);a[0]=-1000000000;for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)  if (a[i]==b[j])  {   for (int k=0;k<i;k++)    if (a[k]<a[i]) f[i][j]=max(f[i][j],f[k][j-1]+1);   f[i][j]=max(f[i][j],f[i][j-1]);  }  else f[i][j]=f[i][j-1];int ans=0;for (int i=1;i<=n;i++) ans=max(ans,f[i][n]);printf("%d\n",ans);}

但是其实还可以优化成O(n^2)的

因为a[i]是固定的,并且只有a[i]=b[j]的时候才需要枚举。条件a[k]<a[i],其实就等价于a[k]<b[j],那么我们先枚举i,再枚举j

当遇到a[i]<b[j]的时候,更新maxn[j]记录的答案,maxn[j]=max(maxn[j],f[i][j]),在枚举到a[i]==b[j]的时候,就可以用maxn[j]数组O(1)更新答案了。

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#define N 3003using namespace std;int n,m,f[N][N],a[N],b[N],maxn[N];int main(){freopen("a.in","r",stdin);scanf("%d",&n);for (int i=1;i<=n;i++) scanf("%d",&a[i]);for (int i=1;i<=n;i++) scanf("%d",&b[i]);a[0]=-1000000000;for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) {  if (a[i]==b[j]) f[i][j]=max(f[i][j],maxn[j]+1);  f[i][j]=max(f[i][j],f[i][j-1]);  if (b[j]>a[i]) maxn[j]=max(maxn[j],f[i][j]);   }int ans=0;for (int i=1;i<=n;i++) ans=max(ans,f[i][n]);printf("%d\n",ans);}


0 0
原创粉丝点击