2019牛客暑期多校第一場 E題ABBA

2022-08-21 16:36:10 字數 1907 閱讀 5876

題目鏈結有(n

+m)(

n+m)

個字母a和(n+

m)(n

+m)個字母b,組成乙個長度為 2∗(

n+m)

2∗(n

+m)的字串,並且使得字串中有n

n個「ab」和m

m個「ba」,求出可能的組合數(mod 1e9+7)

例如,n = 1 m = 2時,可以有這樣的字串(並不是全部的字串):

abbaba

abbbaa

bbabaa

上面三個字串均滿足條件

考慮遞推,假設已經有乙個字串滿足一定的「先決條件」(此處應當理解為數學歸納法,及假設n - 1時滿足)

下面考慮在字串最後加入乙個字元的情況。僅有兩種可能:加a或者加b(這不是白說嗎)

但是考慮一下極端情況,我們可以得到一些簡單的且明顯的條件(na表示已經在字串中的a個數,nb同理)

假如字串的組成類似這樣:

aaaaabbbbbbbb

則此字串中,只能組合出 ab 而不可能組合出 ba

此時,我們假設 n

n 為 5

而這個字元只能且必定要組合成 5 個ab,也就是說,我們接下來加入字元,只能加入 a 而不能加入 b

此時我們往前推,如果出現了這樣乙個字串,則在之前,必定出現如下狀態:

aaaaa

也即是 5 個a的情況,此時我們可以得到乙個確定的關係式:

nb = 0 and na

<= n

推廣到有b的情況,最優的情況就是所有的b都是用來組成ba,那麼可以得到我們真正需要的關係式:

na - nb

<= n

同理,相對於 b 而言,我們可以得到

nb - na

<= m

合併上述兩式

-n < na - nb

<= m

所以根據下標為 na - nb 建立dp陣列,下標範圍為 -n 到 m (均包含)dp的內容為方案數量(mod 1e9 + 7),遞推公式為dp

[i]=

dp[i

−1]+

dp[i

+1]d

p[i]

=dp[

i−1]

+dp[

i+1]

其中,dp[i - 1]指的是加入乙個b(增加乙個b使得na - nb變小)。而dp[i + 1]指的是加入乙個a

當考慮到無論是正向dp還是逆向dp,均有值優先於dp[i]先更新(dp[i - 1]和dp[i + 1]會比dp[i]先更新),所以採用兩個dp陣列的方式,初始值dp[0]=1。每兩次dp完後,dp[0]的值及為答案。

#include

using namespace std;

#define maxn 2100

#define mod (int)(1e9 + 7)

typedef

long

long ll;

ll dp[maxn][2

];inttrans

(int x)

intmain()

if(j != m)

}for

(int j =

-n; j <= m; j++

)swap

(cur, last);}

cout << dp[n]

[last]

<< endl;

}return0;

}

2023年牛客多校第一場 E題 ABBA DP

傳送門首先我們知道 a 在放了 n 個位置裡面是沒有約束的,b 在放了 m 個位置裡面也是沒有約束的,其他情況見下面情況討論。dp i j 表示放了 i 個 a 和 j 個 b 的方案數,然後考慮轉移到下乙個狀態 include include include include include inc...

2019牛客多校第一場

看到這裡我還能說什麼呢?自己慢慢證吧 就是這個 而 了 大佬們的結論是 三角形面積的22倍。我.手動膜拜。不會證.while true try x1,y1,x2,y2,x3,y3 map int,input split s abs x1 y2 x2 y1 x2 y3 x3 y2 x3 y1 x1 y...

2019 牛客多校 第一場

a 題意 就是兩個陣列,找最大的p,使對於1到p的所有子區間都保證最小值的下標相同 題解 每次往後加乙個值 第i 1位 都會多出 i 個區間,當a i 1 大於max a 1 a i 時沒有影響,當a i 小於max a 1 a i 時,因為a i 1 的加入會導致區間的rmq l到r 的 最小值的...