LCS
求两个字符串的公共子串
a[1][1]=same(1,1);
a[i,j] = max{a[i-1][j -1] + same(i,j),a[i-1,j],a[i,j-1]}
#include<stdio.h> #include<string.h> char s[1000],t[1000]; int a[1000][1000]; int main() { int i,j,len1,len2; while(scanf("%s %s",s,t)!=EOF) { len1=strlen(s); len2=strlen(t); for(i=1;i<=len1;i++) for(j=1;j<=len2;j++) if(s[i-1]==t[j-1]) a[i][j]=a[i-1][j-1]+1; else { if(a[i][j-1]>a[i-1][j]) a[i][j]=a[i][j-1]; else a[i][j]=a[i-1][j]; } printf("%d ",a[len1][len2]); } }
LIS
O(n*n)算法
dp[i]=mX(dp[j])+1 (j>=0&&j<=i&&a[j]<a[i]);
#include<stdio.h> int a[5000]; int dp[5000]; int main() { int n,i,j,ans,temp; while(scanf("%d",&n)!=EOF) { ans=0; for(i=0;i<n;i++) scanf("%d",&a[i]); for(i=0;i<5000;i++) dp[i]=1; for(i=1;i<n;i++) { temp=0;; for(j=0;j<=i;j++) if(a[j]<a[i]&&temp<dp[j]) temp=dp[j]; dp[i]=temp+1; } for(i=0;i<n;i++) if(ans<dp[i]) ans=dp[i]; printf("%d ",ans); } return 0; }
LIS还有O(nlogn)的算法,不过还没搞懂。
LCIS
O(m*n)的算法
#include<stdio.h> #include<string.h> int a[1000],b[1000]; int dp[1000]; int main() { int t,m,n,i,j; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(i=0;i<m;i++) scanf("%d",&b[i]); memset(dp,0,sizeof(dp)); int ans=0,k; for(i=0;i<n;i++) { k=0; for(j=0;j<m;j++) { if(b[j]<a[i]&&dp[j]+1>dp[k]) k=j; if(b[j]==a[i]&&dp[j]<dp[k]+1) dp[j]=dp[k]+1; } } for(i=0;i<m;i++) { if(ans<dp[i]) ans=dp[i]; } printf("%d ",ans); if(t!=0) printf(" "); } return 0; }
LCIS可参考这个链接http://www.clarkok.com/blog/?p=353
下面给几个有关这类的题的链接
hdu 1159 http://acm.hdu.edu.cn/showproblem.php?pid=1159 LCS题
hdu 1513 http://acm.hdu.edu.cn/showproblem.php?pid=1513 LCS 不过要用到滚动数组
hdu 4545 http://acm.hdu.edu.cn/showproblem.php?pid=4545 LCS
hdu 1257 http://acm.hdu.edu.cn/showproblem.php?pid=1257 LIS
hdu 1423 http://acm.hdu.edu.cn/showproblem.php?pid=1423 LCIS
hdu 1677 http://acm.hdu.edu.cn/showproblem.php?pid=1677 LIS 不过要用O(n*logn)的