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; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮