題目描述
羅老師又在構造字串了,他有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...