• 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

      

  • 相关阅读:
    每日学习
    每日学习——iframe标签伪造ajax
    每日总结
    LA 3667 Ruler
    hdu 2066 一个人的旅行 (dij+heap)
    LA 3507 Keep the Customer Satisfied (Greedy)
    hdu 2527 Safe Or Unsafe
    LA 4636 Cubist Artwork
    hdu 4514 湫湫系列故事——设计风景线(树DP)
    LA 4328 Priest John's Busiest Day (Greedy)
  • 原文地址:https://www.cnblogs.com/wmq12138/p/10363982.html
Copyright © 2020-2023  润新知