最长上升子序列O(n*log(n))的做法,只能用于求长度不能求序列。
#include <iostream> #define SIZE 1001 using namespace std; int main() { int i, j, n, top, temp; int stack[SIZE]; while(cin >> n) { top = 0; /* 第一个元素可能为0 */ stack[0] = -1; for (i = 0; i < n; i++) { cin >> temp; /* 比栈顶元素大数就入栈 */ if (temp > stack[top]) { stack[++top] = temp; } else { int low = 1, high = top; int mid; /* 二分检索栈中比temp大的第一个数 */ while(low<high) { mid=(low+high)/2; if(stack[mid]>temp) high=mid; else low=mid+1; } /* 用temp替换 */ stack[low] = temp; } } /* 最长序列数就是栈的大小 */ cout << top << endl; } return 0; }
这个是既能求长度也能求序列的,复杂度O(n^2)。
Ritchie丶 13:14:42 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=1e3+5; char s1[maxn],s2[maxn]; int b[maxn][maxn],dp[maxn][maxn]; void pr(int i,int j) { if(i==0||j==0) return ; if(b[i][j]==1) { pr(i-1,j-1); printf("%c",s1[i]); } else if(b[i][j]==2) pr(i-1,j); else pr(i,j-1); } int main() { while(scanf("%s%s",s1,s2)!=EOF) { memset(b,0,sizeof(b)); memset(dp,0,sizeof(dp)); int len1=strlen(s1),len2=strlen(s2); for(int i=len1;i>=1;i--) s1[i]=s1[i-1]; for(int i=len2;i>=1;i--) s2[i]=s2[i-1]; for(int i=1;i<=len1;i++) for(int j=1;j<=len2;j++) { if(s1[i]==s2[j]) { dp[i][j]=dp[i-1][j-1]+1; b[i][j]=1; } else if(dp[i-1][j]>dp[i][j-1]) { dp[i][j]=dp[i-1][j]; b[i][j]=2; } else { dp[i][j]=dp[i][j-1]; b[i][j]=3; } } //这个是长度 //printf("%d\n",dp[len1][len2]); //这个是LCS序列 pr(len1,len2); puts(""); } return 0; }
时间: 2024-11-06 22:27:31