BZOJ 2423 (求LCS的長度和種類數)

2022-06-01 01:36:15 字數 2067 閱讀 4620

字串行的子串行是指從給定字串行中隨意地(不一定連續)去掉若干個字元(可能乙個也不去掉)後所形成的字串行。令給定的字串行x=「x0,x1,…,xm-1」,序列y=「y0,y1,…,yk-1」是x的子串行,存在x的乙個嚴格遞增下標序列,使得對所有的j=0,1,…,k-1,有xij = yj。例如,x=「abcbdab」,y=「bcdb」是x的乙個子串行。對給定的兩個字串行,求出他們最長的公共子串行長度,以及最長公共子串行個數。

第1行為第1個字串行,都是大寫字母組成,以」.」結束。長度小於5000。

第2行為第2個字串行,都是大寫字母組成,以」.」結束,長度小於5000。

第1行輸出上述兩個最長公共子串行的長度。

第2行輸出所有可能出現的最長公共子串行個數,答案可能很大,只要將答案對100,000,000求餘即可。

abcbdab.

bacbbd.47

反思:題目雖然看題解看懂了,自己也敲出來了,但是當別人問的時候不能清晰的講出自己思路(甚至還講錯了,這個是真tm尷尬),這樣是失敗的,雖然ac了,然並卵;

這題第2問嚴格的來說並不能算動態規劃(不滿足無後效性),只是借用其中狀態如何轉移;

題解:第一問模板題,第二問不會寫

有2個問題:第lcs的個數,**會爆空間(需要滾動陣列)

f[i][j]表示a前i位,b前j位的最長公共子串行長度,用g[i][j]表示a前i位,b前j位的最長公共子串行數目

g[i][j]如何轉移呢?考慮這是從那一步推過來的,

比如當 f[i][j]=f[i−1][j],就可以認為從f[i-1][j]轉移過來,

那麼g[i][j]=g[i-1][j];

那麼有如下關係式:

當f[i][j]=f[i−1][j],g[i][j]+=g[i−1][j]

當f[i][j]=f[i][j−1],g[i][j]+=g[i][j−1]

當a[i]=b[j]且f[i][j]=f[i−1][j−1]+1,g[i][j]+=g[i−1][j−1],看起來好像沒啥問題,but...樣例都沒法過,orz

其實是忽略了一種情況(本質上是對這個狀態轉移不是特別清晰),

當a[i]≠b[j],並且f[i

][j]

=f[i

−1][

j−1]

'>f[i][j]=f[i−1][j−1]

f[i][j]=f[i−1][j−1],(就是a,b的最後一位均沒有匹配,會導致上面的2個if條件都會滿足,f[

i][j

]=f[

i−1]

[j−1

]'>g[i][j]同時累計上g[i-1][j]和g[i][j-1]時,明顯有重複的情況f[

i][j

]=f[

i−1]

[j−1

]'>。f[

i][j

]=f[

i−1]

[j−1

]'>

1 #include 2 #include 3 #include 4

using

namespace

std;56

const

int mod=100000000;7

const

int maxn=5005;8

char

a[maxn], b[maxn];

9int f[2][maxn],g[2

][maxn];

1011

intmain()

1234

else

3540

if(f[now][j]==f[pre][j])

41 g[now][j]=(g[now][j]+g[pre][j])%mod;

4243

if(f[now][j]==f[now][j-1

])44 g[now][j]=(g[now][j]+g[now][j-1])%mod;45}

46}47 printf("

%d\n%d

",f[n&1][m],g[n&1

][m]);

48return0;

49 }

bzoj 2423 最長公共子串行

題意 中文題意,略。思路 第一問,求最長公子序列,模板題。第二問,求最長公共子串行的個數,這個就比較有意思了。設len i j 表示表示第乙個串到i位置,第二個串到j位置時的長度。設lcs i j 表示第乙個串到i位置,第二個串到j位置時,lcs的個數。當a i b j 那麼最長公共子串行肯定是可以...

BZOJ2423 最長公共子串行(動態規劃)

bzoj 洛谷今天考試的時候,神仙出題人 fdf 把這道題目作為乙個二合一出了出來,我除了orz還是只會orz。對於如何 o n 2 求解最長的長度是很簡單的。設 f i j 表示第乙個串匹配到了 i 第二個串匹配到了 j 的最大長度。那麼轉移很顯然,要麼 i 向後挪動一位,要麼 j 向後挪動一位,...

求N階乘的長度

給乙個數x,len log10 x 1就是x這個數的長度 當n的值不超過10 6時 那麼n的階乘長度 log10 1 2 3 4 n 1 log10 1 log10 2 log10 3 log10 4 log10 n 1 include includeint main 當n比較大時,再用上面這種方法...