返回顶部

AcWing 272. 最长公共上升子序列 (DP)

  • 题意:找出LCIS

  • 题解:我们设\(dp[i][j]\)\([a_1,a_i]\)\([b_1,b_j]\)组成的并且以\(b_j\)结尾的最长公共上升子序列,若\(a[i]!=b[j]\),那么\(dp[i][j]=dp[i-1][j]\),如果\(a[i]=b[j]\),那么我们就固定\(a[i]\),从\(dp[i-1][1...j-1]+1\)转移过来.

  • 代码:

    #include <bits/stdc++.h>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    #define rep(a,b,c) for(int a=b;a<=c;++a)
    #define per(a,b,c) for(int a=b;a>=c;--a)
    const int N = 1e6 + 10;
    const int mod = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<ll,ll> PLL;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b) {return a/gcd(a,b)*b;}
     
    int dp[3010][3010];
     
    int main(){
        ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
        int n;
        cin>>n;
        vector<int> a(n+1),b(n+1);
    
        rep(i,1,n) cin>>a[i];
        rep(i,1,n) cin>>b[i];
    
    /*
        rep(i,1,n){
            rep(j,1,n){
                dp[i][j]=dp[i-1][j];
                if(a[i]==b[j]){
                    int maxv=1;
                    rep(k,1,j-1){
                        if(b[k]<a[i]){
                            maxv=max(maxv,dp[i-1][k]+1);
                        }
                    }
                    dp[i][j]=max(dp[i][j],maxv);
                }
            }
        }
        O(n^3)
    */
    
        int ans=0;
        rep(i,1,n){
            int maxv=1;
            rep(j,1,n){
                dp[i][j]=dp[i-1][j];
                if(a[i]==b[j]){
                    dp[i][j]=max(dp[i][j],maxv);
                }
                if(b[j]<a[i]) maxv=max(maxv,dp[i-1][j]+1);
                ans=max(ans,dp[i][j]);
            }
        }
    
        cout<<ans<<'\n';
     
     
        return 0;
    }
    
posted @ 2021-04-09 00:53  Rayotaku  阅读(35)  评论(0编辑  收藏  举报