/************************* 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; }