子串的概率

2021-08-09 07:38:30 字數 1855 閱讀 8641

題目描述

羅老師又在構造字串了,他有n個字母庫(這些字母都是小寫字母),每個字母都有被選用的概率(他們的概率之和為1)。他想使用這些字母組成乙個長度為m的字串s,那麼這個字串的各種組成形式都有一定的概率。

這樣漫無目的的構造字串很無聊,所以羅老師就想,再給定乙個字串t,他想知道t是s子串的概率有多少?

輸入 第一行輸入n, m

接下來n行,每行輸入乙個小寫字母及其被選概率

最後一行輸入字串t

輸出 輸出t是s子串的概率(寫成百分比形式,保留2位小數)

樣例輸入

4 10

w 0.25

o 0.25

r 0.25

d 0.25

word

樣例輸出

2.73%

提示 【樣例說明】

其他樣例1:

2 10

a 1.0

b 0.0

abc輸出:

0.00%

其他樣例2:

2 100

a 0.312345

b 0.687655

abab

輸出:98.54%

【資料規模和約定】

1<=n<=26 1<=m<=1000

題解 給你將n個字母打出來的概率,讓你求打出乙個字串長度為m的串,其中串s為它的子串的概率。

先特判不可能組成的,再就是dp[i][j],第一維i代表當前達到了第i個字元,第二維代表當前到達了s串的第j個字元。

當打出下乙個字元為s[j + 1],是狀態轉移為dp[i + 1][j + 1] = dp[i][j] * p;當打出下乙個字元不是j + 1時,找到它的next陣列中的值,即kmp演算法,如果找到乙個當前串的最大的相等的前字尾,狀態轉移為dp[i + 1][id + 1] = dp[i][j] * p;如果get_next的返回值為0,需要判斷當前字元是否與s串的第乙個相等如果相等,狀態轉移為dp[i + 1][1] = dp[i][j] * p;否則,狀態轉移為dp[i + 1][0] = dp[i][j] * p。

**

#include

#define mod 1000000009

#define inf 10000000

#define n 1000105

#define pa pair

typedef

long

long ll;

using

namespace

std;

inline

int read()

while (ch>='0'&&ch<='9')

return x*f;

}int n,m,len;

double p[27],dp[1005][1005],ans;

char s[1005],ch[1005],s[1005];

int next[1005];

void kmp()

next[0]=0;

}int main()

scanf("%s",s+1);

len=strlen(s+1);

kmp();

dp[0][0]=1;

for (int i=0;ifor (int j=0;jfor (int x=1;x<=n;x++)

if (ch[x]==s[j+1]) dp[i+1][j+1]+=dp[i][j]*p[x];

else

for (int i=1;i<=m;i++) ans+=dp[i][len];

ans*=100.0;

printf("%.2lf%%",ans);

return

0;}

子串行 子串

def foo num list 求陣列中最大子串行的和,子串行必須連續 length len num list max value 10000000000 tmp 0 for i in range length tmp max tmp num list i num list i max value...

子串行 子串

1 第一種思路模板是乙個一維的 dp 陣列 int n array.length int dp newint n for int i 1 i n i 例如 最長遞增子串行 在這個思路中 dp 陣列的定義是 在子陣列 array 0 i 中,我們要求的子串行 最長遞增子串行 的長度是 dp i 2 第...

String按照子串反轉目標串的子串內容

string 類有乙個reverse 方法可以直接反轉整個字串,但並未提供按照自己提供的子串的能進行反轉。我們使用kmp演算法,先找到匹配的最後的乙個下標再進行反轉,再拼接。一 public static string reverse string s,string t else k i int m...