LCS/LIS/LCIS 模板总结
/************************* 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:最长上升子序列 POJ 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; }