HDU 1423 最长公共字串+上升子序列
http://acm.hdu.edu.cn/showproblem.php?pid=1423
在前一道题的基础上多了一次筛选
要选出一个最长的递增数列
lower_bound()函数很好用,二分搜索找出满足ai>k的ai最小指针
还有upper_bound()
头文件#include<algorithm>
比如求长度为n的数组a中k的个数:upper_bound(a,a+n,k)-lower_bound(a,a+n,k)
int 放在main函数里面声明会出现程序崩溃,放在全局就没有问题,这里不知原因
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF = 0x3f3f3f3f; int i,j,n,m,h,a,b; int s[600],t[600],lable[600][600],dp[600][600]; int ai[600],dpp[600]; void mem() { memset(s,0,sizeof(s)); memset(t,0,sizeof(s)); memset(ai,0,sizeof(s)); memset(dpp,0,sizeof(s)); for(i=1;i<600;i++) { memset(dp[i],0,sizeof(s)); memset(lable[i],0,sizeof(s)); } } int main() { int NN; scanf("%d",&NN); while(NN--) { mem(); scanf("%d",&n); for(i=0;i<n;i++) { scanf("%d",&s[i]); } scanf("%d",&m); for(i=0;i<m;i++) { scanf("%d",&t[i]); } for(i=0;i<n;i++) { for(j=0;j<m;j++) { if(s[i]==t[j]) { dp[i+1][j+1]=dp[i][j]+1; lable[i+1][j+1]=1; } else { if(dp[i][j+1]>dp[i+1][j]) { dp[i+1][j+1]=dp[i][j+1]; lable[i+1][j+1]=2; } else { dp[i+1][j+1]=dp[i+1][j]; lable[i+1][j+1]=3; } } } } a=n;b=m; h=dp[n][m]; while(lable[a][b]!=0) { if(lable[a][b]==1) { a--;b--;h--; ai[h]=s[a];//or t[b] } else if(lable[a][b]==2) { a--; } else if(lable[a][b]==3) { b--; } } fill(dpp,dpp+n,INF); h=dp[n][m]; for(i=0;i<h;i++) { *lower_bound(dpp,dpp+h,ai[i])=ai[i]; } cout<<lower_bound(dpp,dpp+n,INF)-dpp<<endl; if(NN) cout<<endl; } return 0; }