LCS/LIS/LCIS 模板总结
来源:互联网 发布:金融数据分析导论 编辑:程序博客网 时间:2024/05/22 13:41
/*************************LCS/LIS/LCIs模板总结:*************************//*****************************************************LCS:最长公共子序列求长度为 len1 的序列 A 和长度为 len2 的序列 B 的LCS注意:序列下标从 0 开始滚动数组写法。返回 LCS 长度*****************************************************/int LCS(int len1,int len2){ memset(dp, 0, sizeof(dp)); for(int i = 1; i <= len1; i++) { for(int j = 1; j <= len2; j++) { if(s1[i-1] == s2[j-1]) dp[i%2][j] = dp[(i-1)%2][j-1]+1; else { int m1 = dp[(i-1)%2][j]; int m2 = dp[i%2][j-1]; dp[i%2][j] = max(m1, m2); } } } return dp[len1%2][len2];}/*******************************************LIS:最长上升子序列 hdu 1257 最少拦截系统********************************************/#include<stdio.h>#include<algorithm>using namespace std;const int maxn = 1000+10;const int INF = 30000+10;int a[maxn]; //导弹高度int h[maxn]; // h[i] 表示当前第 i 个系统拦截的高度int main(){ int n; while(scanf("%d", &n) != EOF) { for(int i = 0; i < n; i++) { scanf("%d", &a[i]); // h[i] = INF; } h[0] = -1; //保证边界递增 h[1] = a[0]; //第一个 int len = 1; //当前已经确立长度 for(int i = 1; i < n; i++) { int index = lower_bound(h,h+len+1,a[i])-h; //保证 h[index] 是数组 h 中第一个 >= a[i] 的 h[index] = a[i]; if(index > len) len = index; } printf("%d\n", len); } return 0;}/***************************************************LCIS:最长公共上升子序列求序列 A 长度为 N 和序列 B 长度为 M 的 LCS序列下标从 1 开始返回 LCS 长度*****************************************************/int dp[maxn];int LCS(int n, int m){ memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) { int tmp = 0; // 存 i 确定, 且 a[i] > b[j] 时最大的 dp[j] for(int j = 1; j <= m; j++) { if(a[i] > b[j] && dp[j] > tmp) tmp = dp[j]; else if(a[i] == b[j]) dp[j] = tmp+1; } } int ans = 0; for(int i = 1; i <= m; i++) ans = max(ans, dp[i]); return ans;}