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

      

  • 相关阅读:
    文化课随笔
    微积分与无穷级数
    [康复计划]-数论基础
    [Codeforces]CF742(Div.2)A-E
    第一次个人编程作业的过程和想法
    第一次个人编程作业
    Python命令行参数及文件读出写入
    第一次个人编程作业
    第一次个人编程作业
    第一次博客作业
  • 原文地址:https://www.cnblogs.com/wmq12138/p/10363982.html
Copyright © 2011-2022 走看看