牛客 A.托米的字符串(求期望、前缀)

题目链接:点击这里
在这里插入图片描述

设随机变量 X X 为 “元音 ( a , e , i , o , u , y ) (a,e,i,o,u,y) 字母占子串长度比”,求 X X 的期望。

长度为 1 1 的子串有 n n 个,

长度为 2 2 的子串有 n 1 n-1 个,

长度为 3 3 的子串有 n 2 n-2 个,

… …

长度为 n n 的子串有 1 1 个,

所以,子串总共有 n ( n + 1 ) 2 \frac{n(n+1)}{2} 个。

随机取一个子串,等概率,即 P ( X ) = 1 n ( n + 1 ) 2 P(X) = \frac{1}{\frac{n(n+1)}{2}}

l e g i l i m e n s legilimens 为例进行推导, X X 的分布列为:

长度为 1 1 的子串:

X 0 1 \frac{0}{1} 1 1 \frac{1}{1} 0 1 \frac{0}{1} 1 1 \frac{1}{1} 0 1 \frac{0}{1} 1 1 \frac{1}{1} 0 1 \frac{0}{1} 1 1 \frac{1}{1} 0 1 \frac{0}{1} 0 1 \frac{0}{1}
P 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55}

长度为 2 2 的子串:

X 1 2 \frac{1}{2} 1 2 \frac{1}{2} 1 2 \frac{1}{2} 1 2 \frac{1}{2} 1 2 \frac{1}{2} 1 2 \frac{1}{2} 1 2 \frac{1}{2} 1 2 \frac{1}{2} 0 2 \frac{0}{2}
P 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55} 1 55 \frac{1}{55}

… …

长度为 10 10 的子串:

X 4 10 \frac{4}{10}
P 1 55 \frac{1}{55}

E ( X ) = X i P i = 1 55 ( 4 1 + 8 2 + . . . . . . + 4 10 ) E(X) = \sum X_iP_i = \frac{1}{55}(\frac{4}{1}+\frac{8}{2}+......+\frac{4}{10}) 可得到一般结论如下:

s u m [ i ] sum[ i ] 表示前 i i 个字母中元音字母个数,

令长度为 i i 的子串中元音字母出现的个数之和为 f [ i ] f[ i ]

f [ 1 ] = s u m [ n ] f[ 1 ]=sum[ n ]

f [ 2 ] = f [ 1 ] + s u m [ n 1 ] s u m [ 1 ] f[ 2 ]=f[ 1 ]+sum[n−1]−sum[ 1 ] (即在 f [ 1 ] f[1] 的基础上, s u m [ n 1 ] s u m [ 1 ] sum[n−1]−sum[1] 这部分要再算一遍)

f [ 3 ] = f [ 2 ] + s u m [ n 2 ] s u m [ 2 ] f[ 3 ]=f[ 2 ]+sum[n−2]−sum[ 2 ] (即在 f [ 2 ] f[2] 的基础上, s u m [ n 2 ] s u m [ 2 ] sum[n−2]−sum[2] 这部分要再算一遍)

⋯⋯

最后答案是 ( f [   i   ] / i ) n ( n + 1 ) / 2 \frac{\sum \left( f[\ i\ ]\right/i)}{n(n+1)/2}

AC代码如下:

#include<iostream>
using namespace std;
long long sum[1000010], f[1000010]; 

int main()
{
    string s;
    cin>>s;
    int len = s.length();
    
    for(int i = 0, j = 1; i < len; j++, i++)
    {
    	if(s[i]=='a'||s[i]=='e'||s[i]=='i'||s[i]=='o'||s[i]=='u'||s[i]=='y')
    		sum[j] = sum[j-1] + 1;
    	else
    		sum[j] = sum[j-1];
	}
	
	for(int i = 1; i <= len; i++)
		f[i] = f[i-1] + sum[len-i+1] - sum[i-1];
	
	double ans = 0;
	for(int i = 1; i <= len; i++)
		ans += f[i]*1.0/i;
	
	printf("%0.9f\n", ans/(1.0*len*(len+1)/2.0));
	return 0;
}
发布了690 篇原创文章 · 获赞 103 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104072479
今日推荐