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

注释1是把三重循环优化成二重(maxlen只跟a[i]和前b的前j-1个前缀有关,而j是从小到大枚举的,可以在枚举的过程中处理)
注释2是把二维数组优化为一维(观察可知f[i][j]可以被f[j]覆盖掉而不影响结果)
优化完成后的代码就非常反直觉了(在我看来),所以以后dp题最好先自己把朴素的思路想出来,再一步步优化
#include<bits/stdc++.h>
using namespace std;

#define fr first
#define se second

typedef pair<int, int> PII;
typedef long long LL;
typedef unsigned long long ULL;

const int INF = 0X3f3f3f3f, N = 3000 + 10, MOD = 1e9 + 10;

int a[N],b[N];
// int f[N][N]; 2
int f[N];

void work() {
	int n;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++) cin>>b[i];
    
    for(int i=1;i<=n;i++){
        int maxlen=1;
        for(int j=1;j<=n;j++){
            // f[i][j]=f[i-1][j]; 2
            if(a[i]==b[j]){
                // int maxlen=1;  1
                // for(int k=1;k<j;k++){  1
                    // if(a[i]>b[k])  1
                        // maxlen=max(maxlen,f[i-1][k]+1);  1
                // }  1
                f[j]=max(f[j],maxlen);
                
            }
            if(a[i]>b[j]) maxlen=max(maxlen,f[j]+1);
        }
    }
    
    int res=0;
    for(int i=1;i<=n;i++){
        // res=max(res,f[n][i]);  2
        res=max(res,f[i]);
    } 
    
    cout<<res<<endl;
}

signed main() {
	
	work();
	
	return 0;
}
posted @ 2022-06-25 17:46  xhy666  阅读(33)  评论(0)    收藏  举报