日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【bzoj2423】最长公共子序列[HAOI2010](dp)

發(fā)布時(shí)間:2025/3/19 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【bzoj2423】最长公共子序列[HAOI2010](dp) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  題目傳送門(mén):http://www.lydsy.com/JudgeOnline/problem.php?id=2423

  題目大意:求兩個(gè)字符串的最長(zhǎng)公共子序列長(zhǎng)度和最長(zhǎng)公共子序列個(gè)數(shù)。

  這道題的話,對(duì)于神犇來(lái)說(shuō),肯定是一眼看出狀態(tài)轉(zhuǎn)移方程的。而我這個(gè)蒟蒻,看了幾篇博客之后才看懂。。。

  第一問(wèn)模板lcs,大家肯定都會(huì),就是設(shè)f[i][j]為A串跑到第i位,B串跑到第j為時(shí)的最長(zhǎng)公共子序列長(zhǎng)度,然后就有:

    f[i][j]=f[i-1][j-1]+1  (a[i]==b[j])

       ?=max(f[i-1][j],f[i][j-1])  (a[i]!=b[j])  (原諒我不會(huì)編輯公式)

  我就解釋一下第二問(wèn)的方程。先設(shè)g[i][j]為A串跑到第i位,B串跑到第j為時(shí)的最長(zhǎng)公共子序列個(gè)數(shù),方程就是這樣:

    g[i][j]=g[i-1][j-1]

        +g[i-1][j]  (f[i][j]==f[i-1][j])

        +g[i][j-1]  (f[i][j]==f[i][j-1])

        (a[i]==b[j])

       =g[i-1][j]  (f[i][j]==f[i-1][j])

        +g[i][j-1]  (f[i][j]==f[i][j-1])

        -g[i-1][j-1]  (f[i][j]==f[i-1][j-1])

        (a[i]!=b[j])

  這里當(dāng)a[i]和b[j]相同時(shí),g[i-1][j],g[i-1][j-1],g[i][j-1]這三個(gè)的最長(zhǎng)公共子序列不會(huì)重復(fù),因?yàn)檫@里的g[i-1][j-1]實(shí)際上還要在末尾添加上a[i](或b[j]),因此這些lcs全都是以a[i],b[j]結(jié)尾的,而g[i-1][j]不包含以a[i]結(jié)尾的lcs,g[i][j-1]不包含以b[j]結(jié)尾的lcs,因此這三類(lèi)lcs不會(huì)重復(fù),可以直接相加。

  當(dāng)a[i]與b[j]不同時(shí),最后當(dāng)f[i][j]==f[i-1][j-1]時(shí)要減去g[i-1][j-1]就是因?yàn)檫@時(shí)g[i-1][j-1]被分別包含在g[i-1][j]和g[i][j-1]中,算了兩次,要把重復(fù)的減掉。

  于是就可以愉快地AC這道題了。

  還有,一定要用滾動(dòng)數(shù)組,不然爆!空!間!

丑代碼:

#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; const int mod=100000000; int f[2][5010],g[2][5010]; char a[5010],b[5010]; int main() {int i,j,n,m;scanf("%s%s",a,b);n=strlen(a)-1; m=strlen(b)-1;for(i=0;i<=m;i++)g[0][i]=1; g[1][0]=1;for(i=1;i<=n;i++)for(j=1;j<=m;j++)if(a[i-1]==b[j-1]){f[i&1][j]=f[i&1^1][j-1]+1;g[i&1][j]=(g[i&1^1][j-1]+(f[i&1^1][j]==f[i&1][j])*g[i&1^1][j]+(f[i&1][j-1]==f[i&1][j])*g[i&1][j-1])%mod;}else{if(f[i&1^1][j]>f[i&1][j-1])f[i&1][j]=f[i&1^1][j];else f[i&1][j]=f[i&1][j-1];g[i&1][j]=((f[i&1^1][j]==f[i&1][j])*g[i&1^1][j]+(f[i&1][j-1]==f[i&1][j])*g[i&1][j-1]-(f[i&1][j]==f[i&1^1][j-1])*g[i&1^1][j-1]+mod)%mod;}printf("%d\n%d",f[n&1][m],g[n&1][m]); } View Code

?

轉(zhuǎn)載于:https://www.cnblogs.com/quzhizhou/p/6978170.html

總結(jié)

以上是生活随笔為你收集整理的【bzoj2423】最长公共子序列[HAOI2010](dp)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。