禁止字串(大白p368)

2021-08-04 02:23:49 字數 1718 閱讀 2011

考慮只由』a』,』g』,』c』,』t』四種字元組成的dnf字串 給定乙個長度為k的字串s,計算長度恰好為n的且不包含s的字串的個數輸入結果對10009取模 。

1<=k<=100

1<=n<=10000

輸入:

n = 3, k = 2, s = 「at」

輸出:

56思路:字串預處理+動態規劃;

在以下**中有兩個陣列next[i][j] 與dp[i][j] 分別代表了以上思路的兩個處理。

首先next[i][j] 表示的是對於字串s的預處理,其規模為n*4;

next[i][j] 表示的是當前列舉到的字串的末尾的i個字元與s的前i個字元一樣的時候,當下乙個列舉到的字元是j(這裡j的取值是0~4 分別代表著「a, g, c, t」)的時候,其構造的新串末尾有i個字元與s的的前i個字元一樣的數量。

以上的這段話請細細體會下, 也可以通過下面的舉例進行理解。

比如 s = 「atcg」 next[1][0] 代表的是當前串的末尾是a現在多加乙個a所以當前列舉到的串的末尾變成了aa, 與s相比其匹配數還是1;

所以: next[1][0] = 1;

同理 next[1][1] = 0;

對於s = 「atcg」 next為:

1 0 0 0

1 0 0 2

1 0 3 0

1 4 0 0

有時會有重複的情況請按匹配最大值儲存:例如 s = 「atcatcg」

如果當前列舉到的字串末尾是atcat 下一位列舉的是c的話那麼對於next[5][2] 可以等於3 也可以等於6, 這個時候按6算。

當構造出next以後 再看dp的狀態轉移方程。

dp[i][j] 表示當前列舉到第i個字元的時候末尾有j個元素與s的前j個元素想匹配的,滿足題目要求的字串個數(也就是說當前字串中沒有s出現的字串個數);

此時 i 表示的是階段(有n+1個階段), j表示當前階段下的狀態(有k個)。

所以 dp[i+1][j] += dp[i][m] ( 0 <= m <= k) 在這裡並非累加所有的,要去掉那些違反題目條件的。

最後**如下:

#include 

#include

#include

#include

#include

using

namespace

std;

int n,k;

string s;

const

char *agct = "agct";

const

int maxn = 1009;

int dp[maxn][108];

int next[maxn][5];

const

int mod = 10009;

void init()

void solve()

next[i][j] = s.length();

} }

for (int i=0;ifor (int x=0;xfor (int j=0;j<4;j++)

} }

int ans = 0;

for (int i=0;icout

<< ans << endl;

} int main()

}

禁止字串 白書P368

考慮只由 a g c t 四種字元組成的dna字串。給定乙個長度為k的字串s,請計算長度恰好為n且不包含s的字串的個數。輸出個數mod 10009後的結果。其中 1 k 100 1 n 10000 輸入n 3 k 2 s at 輸出56 首先考慮最直觀的演算法就是 生成所有滿足條件的字串,但是字串個...

檢測是否含有禁止字串

檢測是否含有禁止字串 如果禁止字串出現次數為 5,測返回 true 引數說明 badwordlist 禁止字元列表 以 號隔開 str 被檢測字串 返回值 boolean 小男 2006 更新 no miss function checkbadword byval badwordlist,byval...

P1032 字串變換 字串

已知有兩個字串 a,b 及一組字串變換的規則 至多6個規則 a1 b1 a2 b2 規則的含義為 在 a 中的子串 a1 可以變換為 b1 a2 可以變換為 b2 例如 a abcd b xyz 變換規則為 abc xu ud y y yz 則此時,a 可以經過一系列的變換變為 b,其變換的過程為 ...