由于本題不需要求出子序列值,所以可以進(jìn)行一定程度的化簡(jiǎn)以及優(yōu)化。既然只需要求出長(zhǎng)度,即圖中最后一行,故可以用全局變量進(jìn)行記錄,將二維數(shù)組化簡(jiǎn)為一維數(shù)組(算法導(dǎo)論的練習(xí)題中有提到)。思路是將一個(gè)序列固定,比如將上圖中yi序列固定不變,xi從1-m增加,即先考慮A,再考慮AB,再考慮ABC......(每次僅需要對(duì)新加入的字符進(jìn)行計(jì)算)。計(jì)算方法是先判斷x[i]與y[j]是否相等,相等則(dp[i] = 上一組dp中的dp[i-1]+1),否則判斷當(dāng)前dp[i]是否比dp[i-1]小,如果是,則dp[i] = dp[i-1],否則(dp[i]=上一組的dp[i])。dp數(shù)組在這里指y序列前i個(gè)值與x序列的LCS,隨著x序列的增長(zhǎng)不斷更新整個(gè)dp數(shù)組。問(wèn)題在與怎么保存上一組的dp[i-1],因?yàn)橛?jì)算當(dāng)前組的dp[i]時(shí)是已經(jīng)計(jì)算完當(dāng)前組的dp[i-1]的,即dp數(shù)組前i-1個(gè)值已經(jīng)更新了,所以這里需要用全局變量來(lái)維護(hù),且僅需要維護(hù)上一組的dp[i-1]這一個(gè)值。具體維護(hù)方法見(jiàn)代碼中olddp和t。代碼如下:#include<iostream>#include<cstdio>#include<cstring>using namespace std;int dp[1000+5];char s1[1000+5],s2[1000+5];int main(){ int N,n,i,j,olddp,t; cin>>N; while(N--) { memset(dp,0,sizeof(dp)); scanf("%s",s1); scanf("%s",s2); for(i = 0;s2[i] != '/0';i++) { olddp=0; for(j = 0;s1[j] != '/0';j++) { t=dp[j]; if(s1[j]==s2[i]) dp[j]=olddp+1; else if(dp[j]<dp[j-1]) dp[j]=dp[j-1]; olddp=t; } } cout<<dp[j-1]<<endl; } return 0;}這里j = x序列的長(zhǎng)度,故dp[j-1]的值即為x序列與y序列的LCS的長(zhǎng)度。可能dp[j-3] = dp[j-2] = dp[j-1],但是dp數(shù)組的最后一個(gè)值一定為最大值。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注