Codevs2185 最长公共上升子序列

来源:互联网 发布:淘宝售后 时间 编辑:程序博客网 时间:2024/06/15 14:37

题目:http://codevs.cn/problem/2185/分析:f[i][j] 表示:a[1]...a[i]和b[1]...b[j]中以b[j]结尾的(并不一定以a[i]结尾,i只是阶段)      则转移为: f[i][j]=max(f[i-1][j'])+1 (a[i]==b[j],j'<j,b[j']<a[i]==b[j])                         =f[i-1][j] (a[i]!=b[j])      可知,此算法是O(n^3)的,我们可以优化为O(n^2)的:      用一个变量_Max记录从1...j-1中最大的且满足a[i]>b[j]的f[i-1][j],则状态转移变为:                 f[i][j]=_Max+1(a[i]==b[j],j'<j,b[j']<a[i]==b[j])                         =f[i-1][j](a[i]!=b[j])代码:#include <cstdio>#include <algorithm>#include <cstring>using namespace std;const int Tmax=3005;int n,A[Tmax],B[Tmax],f[Tmax][Tmax];void work(){int i,j,_Max;for(i=1;i<=n;i++){_Max=0;for(j=1;j<=n;j++){f[i][j]=f[i-1][j];if(A[i]==B[j]) f[i][j]=_Max+1;if(A[i]>B[j]) _Max=max(_Max,f[i-1][j]);}}_Max=0;for(i=1;i<=n;i++)  _Max=max(_Max,f[n][i]);printf("%d",_Max);return;}int main(){int i;scanf("%d",&n);for(i=1;i<=n;i++)  scanf("%d",&A[i]);for(i=1;i<=n;i++)  scanf("%d",&B[i]);work();return 0;}


原创粉丝点击