HDOJ 1159 Common Subsequence 解题报告
经典的题吧,最长公共子序列。
额,一开始想错了,总是超时。看了网上大牛的代码,恍然大悟。AC代码如下:
#include <iostream> using namespace std; int dp[2013][2013]; char a[2013],b[2013]; int main() { int i,j,lena,lenb; while(scanf("%s%s",a,b)!=EOF) { memset(dp,0,sizeof(dp)); lena=strlen(a); lenb=strlen(b); for(i=0;i<lena;i++) for(j=0;j<lenb;j++) dp[i+1][j+1]=a[i]==b[j]?dp[i][j]+1:dp[i][j+1]>dp[i+1][j]?dp[i][j+1]:dp[i+1][j]; cout<<dp[lena][lenb]<<endl; } }
第二次超时的原因是将for(i=0;i<lena;i++)和lena=strlen(a);写在一起,即
for(i=0;i<(lena=strlen(a));i++)
能运行,少两行,答案也不会错,但是会超时。原因在于每次循环都会判断,而(lena=strlen(a))会被执行很多次。。。(lena=strlen(a))会被执行很多次的平方。。。
在比较长的字符串输入中,scanf比cin快,这也是一方面。最终跑的时间是593MS,不知道那个15MS的C++代码是什么样子的。
15MS版,呵呵:
#include <iostream> using namespace std; int dp[2013][2013]; char a[2013],b[2013]; int main() { int i,j,lena,lenb; while(~scanf("%s%s",a,b)) { lena=strlen(a); lenb=strlen(b); for(i=0;i<lena;i++) dp[0][i]=0; for(i=0;i<lenb;i++) dp[i][0]=0; for(i=0;i<lena;i++) for(j=0;j<lenb;j++) dp[i+1][j+1]=a[i]==b[j]?dp[i][j]+1:(dp[i+1][j]>dp[i][j+1]?dp[i+1][j]:dp[i][j+1]); printf("%d\n",dp[lena][lenb]); } }