考慮只由』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,其變換的過程為 ...