HDU 1423 && ZOJ 2432 (LCIS模板)
来源:互联网 发布:双十一每年数据 编辑:程序博客网 时间:2024/05/18 01:01
定义状态
F[i][j]表示以a串的前i个整数与b串的前j个整数且以b[j]为结尾构成的LCIS的长度。
状态转移方程:
①F[i][j] = F[i-1][j] (a[i] != b[j])
②F[i][j] = max(F[i-1][k]+1) (1 <= k <= j-1 && b[j] > b[k])
现在我们来说为什么会是这样的状态转移方程呢?
对于①,因为F[i][j]是以b[j]为结尾的LCIS,如果F[i][j]>0那么就说明a[1]..a[i]中必然有一个整数a[k]等于b[j],因为a[k]!=a[i],那么a[i]对F[i][j]没有贡献,于是我们不考虑它照样能得出F[i][j]的最优值。所以在a[i]!=b[j]的情况下必然有F[i][j]=F[i-1][j]。
对于②,前提是a[i] == b[j],我们需要去找一个最长的且能让b[j]接在其末尾的LCIS。之前最长的LCIS在哪呢?首先我们要去找的F数组的第一维必然是i-1。因为i已经拿去和b[j]配对去了,不能用了。并且也不能是i-2,因为i-1必然比i-2更优。第二维呢?那就需要枚举b[1]...b[j-1]了,因为你不知道这里面哪个最长且哪个小于b[j]。这里还有一个问题,可不可能不配对呢?也就是在a[i]==b[j]的情况下,需不需要考虑F[i][j]=F[i-1][j]的决策呢?答案是不需要。因为如果b[j]不和a[i]配对,那就是和之前的a[1]...a[j-1]配对(假设F[i-1][j]>0,等于0不考虑),这样必然没有和a[i]配对优越。(为什么必然呢?因为b[j]和a[i]配对之后的转移是max(F[i-1][k])+1,而和之前的i`配对则是max(F[i`-1][k])+1。
可以发现,其实上面的代码有些地方与0/1背包很相似,即每次用到的只是上一层循环用到的值,即f[i-1][j],那么我们可以像优化0/1背包问题利用滚动数组来优化空间。如果是求最长公共下降子序列呢?很明显嘛,把状态定义改动一下,即f[i][j]表示以a串的前i个整数与b串的前j个整数且以b[j]为结尾构成的LCDS的长度,具体实现的时候只要把a[i] > b[j]改为a[i] < b[j]就可以啦。
Greatest Common Increasing Subsequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 8249 Accepted Submission(s): 2666
151 4 2 5 -124-12 1 2 4
2
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 5e2 + 5;int dp[maxn], a[maxn], b[maxn], n, m;int main(){ int t; cin >> t; while(t--) { memset(dp, 0, sizeof(dp)); scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); scanf("%d", &m); for(int i = 1; i <= m; i++) scanf("%d", &b[i]); for(int i = 1; i <= n; i++) { int maxx = 0; for(int j = 1; j <= m; j++) { if(a[i] > b[j]) maxx = max(maxx, dp[j]); if(a[i] == b[j]) dp[j] = maxx + 1; } } int ans = 0; for(int i = 1; i <= m; i++) ans = max(ans, dp[i]); if(t != 0) printf("%d\n\n", ans); else printf("%d\n", ans); } return 0;}
You are given two sequences of integer numbers. Write a program to determine their common increasing subsequence of maximal
possible length.
Sequence S1, S2, ..., SN of length N is called an increasing subsequence of a sequence A1, A2, ..., AM of length M if there exist 1 <= i1 < i2 < ...< iN <= M such that Sj = Aij for all 1 <= j <= N, and Sj < Sj+1 for all 1 <= j < N.
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
On the first line of the output print L - the length of the greatest common increasing subsequence of both sequences. On the second line print the subsequence itself. If there are several possible answers, output any of them.
This problem contains multiple test cases!
The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.
The output format consists of N output blocks. There is a blank line between output blocks.
Sample Input
1
5
1 4 2 5 -12
4
-12 1 2 4
Sample Output
2
1 4
Source: Northeastern Europe 2003, Northern Subregion
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;const int maxn = 505;int n, m, t, a[maxn], b[maxn], dp[maxn][maxn], pathx[maxn][maxn], pathy[maxn][maxn], cur, ans;void Printf(int x, int y){ if(dp[x][y] == 0) return; if(pathx[x][y] != -1 && pathy[x][y] != -1) { int tx = pathx[x][y]; int ty = pathy[x][y]; Printf(tx, ty); if(dp[x][y] != dp[tx][ty] && y != 0) { cur++; if(cur < ans) printf("%d ", b[y]); else printf("%d\n", b[y]); } }}int main(){ cin >> t; while(t--) { scanf("%d", &n); for(int i = 1; i <= n; i++) scanf("%d", &a[i]); scanf("%d", &m); for(int i = 1; i <= m; i++) scanf("%d", &b[i]); memset(dp, 0, sizeof(dp)); memset(pathx, -1, sizeof(pathx)); memset(pathy, -1, sizeof(pathy)); int tmpx = 0, tmpy = 0; for(int i = 1; i <= n; i++) { tmpx = 0, tmpy = 0; int maxx = 0; for(int j = 1; j <= m; j++) { dp[i][j] = dp[i-1][j]; pathx[i][j] = i-1; pathy[i][j] = j; if(a[i] > b[j] && maxx < dp[i-1][j]) maxx = dp[i-1][j], tmpx = i-1, tmpy = j; if(a[i] == b[j]) dp[i][j] = maxx+1, pathx[i][j] = tmpx, pathy[i][j] = tmpy; } } ans = 0; int flag = -1; for(int i = 1; i <= m; i++) { if(ans < dp[n][i]) { flag = i; ans = dp[n][i]; } } printf("%d\n", ans); tmpx = n, tmpy = flag; cur = 0; if(tmpy > 0) Printf(tmpx, tmpy); if(t != 0) puts(""); } return 0;}
You are given two sequences of integer numbers. Write a program to determine their common increasing subsequence of maximal
possible length.
Sequence S1, S2, ..., SN of length N is called an increasing subsequence of a sequence A1, A2, ..., AM of length M if there exist 1 <= i1 < i2 < ...< iN <= M such that Sj = Aij for all 1 <= j <= N, and Sj < Sj+1 for all 1 <= j < N.
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
On the first line of the output print L - the length of the greatest common increasing subsequence of both sequences. On the second line print the subsequence itself. If there are several possible answers, output any of them.
This problem contains multiple test cases!
The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.
The output format consists of N output blocks. There is a blank line between output blocks.
Sample Input
1
5
1 4 2 5 -12
4
-12 1 2 4
Sample Output
2
1 4
Source: Northeastern Europe 2003, Northern Subregion
- HDU 1423 && ZOJ 2432 (LCIS模板)
- HDU 5904:LCIS(LCIS)
- hdu 1423 最长上升公共子序列 LCIS 模板题
- HDU 1423 裸LCIS
- zoj 2432 && hdoj 1423 Greatest Common Increasing Subsequence 【打印LCIS】
- hdu LCIS(线段树)
- hdu 3308 LCIS(RE)
- 思维 hdu 5904 (LCIS)
- HDU 5904 LCIS(dp)
- hdu 1423 Greatest Common Increasing Subsequence(LCIS)
- zoj 2127 lcis
- HDU 1423--Greatest Common Increasing Subsequence【LCIS】
- HDU 1423 Greatest Common Increasing Subsequence(LCIS)
- HDU 1423 Greatest Common Increasing Subsequence (LCIS)
- hdu 3308 LCIS (线段树)
- HDU 3308 LCIS(线段树)
- HDU 3308 LCIS(线段树)
- hdu 3308 LCIS(区间合并)
- HDU
- 组装台式机流程
- ngui ui的坐标是相对父物体的中心点的坐标
- 05 java里的多态
- 可以重写静态方法吗?
- HDU 1423 && ZOJ 2432 (LCIS模板)
- 隐藏MainActivity自带的标题栏
- HashMap和Hashtable的区别
- HashMap和HashSet的区别
- Linux下快速收起vim 并暂存修改
- Spring Boot : 集成mybatis、pagehelper插件、开启事务、druid数据源配置、mybatis-generator(十一)
- wget
- Redis的Linux环境下安装配置
- LinkedList和ArrayList的区别