LCIS code force 10D

来源:互联网 发布:高速铣编程用什么软件 编辑:程序博客网 时间:2024/06/09 14:24



This problem differs from one which was on the online contest.

The sequence a1, a2, ..., an is called increasing, if ai < ai + 1 for i < n.

The sequence s1, s2, ..., sk is called the subsequence of the sequence a1, a2, ..., an, if there exist such a set of indexes 1 ≤ i1 < i2 < ... < ik ≤ n that aij = sj. In other words, the sequence s can be derived from the sequence a by crossing out some elements.

You are given two sequences of integer numbers. You are to find their longest common increasing subsequence, i.e. an increasing sequence of maximum length that is the subsequence of both sequences.


这一道题,我用的是O(n^2)的算法,仔细分析一下可以发现,用O(n^3)的算法很危险,所以我建议用O(n^2)的算法

#include<cstdio>

#include<algorithm>

using namespace std;

int y[705],x[705];

int f[705][705];
int path[1005];
int n,m,len,w;
void output(int now){//回朔打印路径
if(now!=0){
output(path[now]);
printf("%d ",y[now]);
}//先找到第一个数,然后在递归输出
}
int main(){
   scanf("%d",&n);
   for(int i=1;i<=n;i++)scanf("%d",&x[i]);
   scanf("%d",&m);
   for(int i=1;i<=m;i++)scanf("%d",&y[i]);
   int ans=0;
   for(int i=1;i<=n;i++){
      len=0,w=0;//len是用来记录x[1....i-1]和y[1...j]的最长子序列的长度
      for(int j=1;j<=m;j++){
         f[i][j]=f[i-1][j];
         if(y[j]<x[i]&&len<f[i-1][j]){更新len,取最大值,替代了k的循环
           len=f[i-1][j],w=j;//记录下来
         }
          if(y[j]==x[i]){
            f[i][j]=len+1,path[j]=w;//我们把路径记录下来,并把f[i][j]用len+1存下来(因为x[1...i]内包括x[1...i-1],y[1...j]内包括y[1...j-1])
          }

       }
   }
   for(int i=1;i<=m;i++){
   if(ans<f[n][i]){
      ans=f[n][i],w=i;//找最大答案
   }
   }
    printf("%d\n",ans);
    if(ans)output(w);
    return 0;
}
原创粉丝点击