Hdu1423 Greatest Common Increasing Subsequence
2017-01-24 00:12
344 查看
Description
This is a problem from ZOJ 2432.To make it easyer,you just need output the length of the subsequence.
Input
Each sequence is described with M - its length (1 <= M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence itself.
Output
output print \(L\) - the length of the greatest common increasing subsequence of both sequences.
Sample Input
1
5
1 4 2 5 -12
4
-12 1 2 4
Sample Output
2
做法一:复杂度\(O(N^3)\)。
我们用\(f_{i,j}\)表示\(A\)数组前\(i\)位,B数组前\(j\)位的最长公共上升子串有多长,但是只有\(A_i = B_j\)的时候有意义。dp方程不难想,但是仔细一算复杂度这是\(O(n^4)\)的,为此我们需要加上一些优化。
我们先枚举\(i\),我们可以维护一个数组\(P\)。其中\[P_j = \max \{ f_{k,j} \},k < i\]
然后dp方程就可以变成\[f_{i,j} = \max\{ P_k+1 \},k < j \; and \; B_k < B_j\]
\(P\)每次dp一个\(i\)都可以\(O(N)\)维护出来。
做法二:复杂度\(O(N^2)\)
令\(g_{i,j} = \max \{ f_{k,j},k \le i \}\),然后我们想想怎么用\(g\)直接来dp。
令\(ma = \max \{ f_{i-1,k},k < j \; and \; A_i > B_k \}\)
首先\[g_{i,j} = g_{i-1,j}\]
然后若\(A_i = B_j\),则\[g_{i,j} = \max\{ g_{i,j},ma+1 \}\]
最后\[ans = \max \{ g_{N,i} \},1 \le i \le M\]
代码1:
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int maxn = 510,inf = 1<<30; int f[maxn][maxn],A[maxn],B[maxn],P[maxn],T,N,M,ans; int main() { freopen("1423.in","r",stdin); freopen("1423.out","w",stdout); scanf("%d",&T); while (T--) { scanf("%d",&N); ++N; A[1] = 0; for (int i = 2;i <= N;++i) scanf("%d",A+i); scanf("%d",&M); ++M; B[1] = 0; for (int i = 2;i <= M;++i) scanf("%d",B+i); for (int i = 1;i <= N;++i) for (int j = 1;j <= M;++j) f[i][j] = -inf; for (int i = 1;i <= M;++i) P[i] = -inf; ans = f[1][1] = P[1] =0; for (int i = 2;i <= N;++i) { for (int j = 2;j <= M;++j) { if (A[i] != B[j]) continue; for (int k = 1;k < j;++k) if (B[k] < A[i]) f[i][j] = max(f[i][j],P[k]+1); ans = max(ans,f[i][j]); } for (int j = 2;j <= M;++j) P[j] = max(P[j],f[i][j]); } printf("%d\n",ans); if (T) puts(""); } fclose(stdin); fclose(stdout); return 0; }
代码2:
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int maxn = 510,inf = 1<<30; int f[maxn][maxn],A[maxn],B[maxn],P[maxn],T,N,M,ans; int main() { freopen("1423.in","r",stdin); freopen("1423.out","w",stdout); scanf("%d",&T); while (T--) { scanf("%d",&N); ++N; A[1] = 0; for (int i = 2;i <= N;++i) scanf("%d",A+i); scanf("%d",&M); ++M; B[1] = 0; for (int i = 2;i <= M;++i) scanf("%d",B+i); for (int i = 1;i <= N;++i) for (int j = 1;j <= M;++j) f[i][j] = -inf; for (int i = 1;i <= M;++i) P[i] = -inf; ans = f[1][1] = P[1] =0; for (int i = 2;i <= N;++i) for (int j = 2,ma = 0;j <= M;++j) { f[i][j] = f[i-1][j]; if (A[i] == B[j]) f[i][j] = ma+1; if (A[i] > B[j]&&ma < f[i-1][j]) ma = f[i-1][j]; } for (int i = 1;i <= M;++i) ans = max(ans,f [i]); printf("%d\n",ans); if (T) puts(""); } fclose(stdin); fclose(stdout); return 0; }
相关文章推荐
- 前端开发利器HBuilder
- 解决mui.openWindow重置slide的问题
- request.getParameterMap()的方法解析
- 关于自定义view中处理事件的探索(一)
- Vue系列之WebPack与Eslint
- Circular Sequence(UVa 1584)
- 跟随手指的小球
- AndroidStudio导入项目一直卡在Building gradle project info最快速解决方案
- 解析 Android 异步消息机制,深入了解 Handler、Looper、MessageQueue 关系
- Ugui 实现简易版的Joystick
- 【PAT】1041. Be Unique
- APUE--环境搭建
- 1051. Pop Sequence
- EasyUI 1.5.1 美化主题 EasyUI 1.5.1 Of Insdep Theme 1.0
- EasyUI 1.5.1 美化主题 EasyUI 1.5.1 Of Insdep Theme 1.0
- Windows Message Queue(优先队列)
- Farey Sequence法里序列
- WPF里面多线程访问UI线程、主线程的控件
- ToolStripMenuItem
- Replace To Make Regular Bracket Sequence(括号匹配)