zoukankan      html  css  js  c++  java
  • CH5101 LCIS

    CH5101 LCIS

    题意:

    求两个长度不超过3000的序列的最长公共上升子序列

    思路: 

    • 朴素解法:用f[i,j]表示a1~ai与b1~bj可以构成的以bj为结尾的LCIS的长度,三重循环求解:
    for(res i=1 ; i<=n ; i++)
        for(res j=1 ; j<=m ; j++)
            if(a[i]==b[j])
            {
               for(res k=1 ; k<j ; k++)
                    if(b[k]<a[i])//a[i]=b[j] 
                       f[i][j]=max(f[i][j],f[i-1][k]+1);
            }
            else
                f[i][j]=f[i-1][j]; 
    • 经过观察可以发现:当外层的i固定时,条件b[k]<a[i]也是固定的,所以当j增加1时,k的取值范围也只增加了1,即只有j可能进入新的决策集合,则可以优化为两重循环:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 using namespace std;
     5 
     6 const int N=3010;
     7 int a[N],b[N];
     8 int f[N][N];
     9 int n;
    10 
    11 int main()
    12 {
    13     scanf("%d",&n);
    14     for(int i=1 ; i<=n ; i++) scanf("%d",&a[i]);
    15     for(int i=1 ; i<=n ; i++) scanf("%d",&b[i]);
    16     
    17     for(int i=1 ; i<=n ; i++)
    18     {
    19         int val=0;//表示决策集合(即f[i-1][k]的最大值) 
    20         for(int j=1 ; j<=n ; j++)
    21         {
    22             if(a[i]==b[j]) f[i][j]=val+1;
    23             else f[i][j]=f[i-1][j];
    24             if(b[j]<a[i])//更新决策集合 
    25                 val=max(val,f[i-1][j]);
    26         }
    27     }
    28     int ans=1;
    29     for(int i=1 ; i<=n ; i++)
    30         ans=max(ans,f[n][i]);
    31     printf("%d
    ",ans);
    32     return 0;    
    33 } 
    View Code

      

  • 相关阅读:
    python之路——进程
    python之路——操作系统的发展史
    python之路——网络编程
    模块学习之re模块
    day11迭代器、生成器
    day10闭包、函数装饰器
    vnc安装和配置
    单例模式
    代理设计模式
    工厂模式例子
  • 原文地址:https://www.cnblogs.com/wmq12138/p/10363982.html
Copyright © 2011-2022 走看看