CH 5101 最长公共上升子序列

题目传送门

题解:F[i][j] 表示 对于第一个数列枚举到i来说, 第二个数列以j结尾的最大长度是多少。

那么对于更新 F[i] -> F[i+1]来说  如果 a[i+1] == b[j] 那么我们就可以找到前面最大F[i][k]( k < j && b[k] < a[i+1])的值, 把他更新。

否则就F[i+1][j] = F[i][j]

最后对于所有的 F[n][k] 找到最大值就好了。

代码:

  

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL mod =  (int)1e9+7;
const int N = 3e3 + 100;
int a[N], b[N];
int f[N][N];
int main(){
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &b[i]);
    for(int i = 1; i <= n; ++i){
        int val = 0;
        for(int j = 1; j <= n; ++j){
            if(a[i] == b[j]) f[i][j] = val + 1;
            else f[i][j] = f[i-1][j];
            if(b[j] < a[i]) val = max(val, f[i-1][j]);
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++)
        ans = max(ans, f[n][i]);
    printf("%d\n", ans);
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/MingSD/p/9928014.html