CF10D 最长公共上升子序列 题解报告

题目传送门

【题目大意】

给定两个序列$a,b$,求最长公共上升子序列。

【思路分析】

这里mark一下最简单的$n^3$做法(并且不记录最长公共上升子序列的数):

$f[i][j]$表示匹配到$a[i]$和$b[j]$的最长公共上升子序列的长度,转移时分情况讨论:

1.$a[i]=b[j]$,则$f[i][j]=max(f[i][j],f[k][j-1]+1)(k\in[0,i-1]\&\&a[i]>a[k])$,注意给$a[0]$赋值为负无穷

2.$a[i]\ne b[j]$,则$f[i][j]=max(f[i-1][j],f[i][j-1])$

还有一种$n^2$做法贴个链接叭QwQ

【代码实现】

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #include<queue>
 7 #define g() getchar()
 8 #define rg register
 9 #define go(i,a,b) for(rg int i=a;i<=b;i++)
10 #define back(i,a,b) for(rg int i=a;i>=b;i--)
11 #define db double
12 #define ll long long
13 #define il inline
14 #define pf printf
15 #define mem(a,b) memset(a,b,sizeof(a))
16 using namespace std;
17 int fr(){
18     int w=0,q=1;
19     char ch=g();
20     while(ch<'0'||ch>'9'){
21         if(ch=='-') q=-1;
22         ch=g();
23     }
24     while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g();
25     return w*q;
26 }
27 const int N=502;
28 int n,m,a[N],b[N],f[N][N];
29 int main(){
30     //freopen("","r",stdin);
31     //freopen("","w",stdout);
32     n=fr();
33     go(i,1,n) a[i]=fr();
34     m=fr();
35     go(i,1,m) b[i]=fr();
36     a[0]=-1;
37     go(i,1,n) go(j,1,m){
38         if(a[i]==b[j])
39             go(k,0,i-1) if(a[i]>a[k]) f[i][j]=max(f[i][j],f[k][j-1]+1);
40                 else f[i][j]=max(f[i-1][j],f[i][j-1]);
41     }
42     pf("%d\n",f[n][m]);
43     return 0;
44 }
代码戳这里
posted @ 2019-09-26 11:37  小叽居biubiu  阅读(219)  评论(0编辑  收藏  举报