Tyvj 1072 LCIS

来源:互联网 发布:python drdos 编辑:程序博客网 时间:2024/05/17 04:18

这个题需要把LIS和LCS合二为一

首先设f(i,j)表示从A1~Ai 和 B1~Bj 两段区间中,以Bj结尾的LCIS最大长度

注意,这里相当于固定住了“Bj是什么”这个问题,并且状态和转移是对于每一个固定的Bj才有意义的

再具体一点,因为关于A1~Ai的循环是套在B1~Bj外面的,所以在进行B1~Bj的循环时,可以将Ai看作一个常量,这个时候对答案有影响的参数就只有i,j和Bj,状态就可以设计出来。
转移:

当 A[i] !=B[j]时

f(i,j)=f(i1,j)

当A[i]==B[j]时
f(i,j)=max{f(i1,k)}+1     0k<jBk<Bj

然而会T。。。
所以这个时候可以转化一下DP方程
可以发现第二种情况时,A[i]==B[j]
所以方程可以写为
f(i,j)=max{f(i1,k)}+1     0k<jBk<Ai

通过上文,我们知道在ij二重循环时,j的循环节内,可以将i看作常数

因此Bk一直都在和一个常数作比较,那么我们就可以开一个变量记下最大且满足条件的fi1k,从而省去了一重循环,但是要记得每次新的i循环开始时要初始化maxf

#include <algorithm>#include <iostream>#include <cstdio>using namespace std;const int INF = 1 << 30;const int MAXN = 3010;int n;int a[MAXN], b[MAXN],ans;int f[MAXN][MAXN],maxf;int main() {    cin >> n;    for(int i=1; i<=n; i++)         cin >> a[i];    for(int i=1; i<=n; i++)        cin >> b[i];    b[0] = -INF;    for(int i=1; i<=n; i++) {           maxf = 0;        for(int j=1; j<=n; j++) {               if(b[j-1] < a[i])                maxf = max(maxf,f[i-1][j-1]);            if(a[i]==b[j])                 f[i][j] = max(f[i][j], maxf + 1);            else                 f[i][j] = f[i-1][j];        }    }    for(int i=1; i<=n; i++)         ans = max(ans,f[n][i]);    cout << ans << endl;    return 0;}
原创粉丝点击