题目分析:
好题。
一开始看错题了,以为是随机选两个球,编号在前的染编号在后的。
但这样仍然能获得一些启发,不难想到可以确定一个颜色,剩下的颜色是什么就无关了。
那么答案就是每种颜色的概率乘以期望。概率很好求。
考虑期望,这里存在一个"黑洞",也就是f[0]状态无论如何也不可能填满颜色,所以我们要舍弃这个状态,这样往左和往右的转移就不是对半了。
通过求出的概率作比可以发现实际上是i-1:i+1。所以可以列出DP方程
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 const int maxn = 10200; 5 char str[maxn]; 6 double h[maxn],f[maxn],g[maxn]; // f->expectation g->possibility 7 8 int cnt[maxn]; 9 double k[maxn],b[maxn]; 10 11 void work(){ 12 int ls = strlen(str); 13 for(int i=0;i<=ls;i++) g[i] = (double)i/(double)ls; 14 for(int i=1;i<ls;i++){ 15 h[i] = (double)ls*(ls-1)/(double)(2*i*(ls-i)); 16 } 17 k[1] = 1; b[1] = h[1]; 18 for(int i=2;i<ls;i++){ 19 b[i] = h[i]; k[i] = (double)(i+1)/(2*i); 20 double hh = k[i-1]*((double)(i-1)/(2*i)); 21 b[i] += b[i-1]*((double)(i-1)/(2*i)); 22 k[i] /= (1-hh); b[i] /= (1-hh); 23 } 24 for(int i=ls-1;i>=1;i--){ 25 f[i] = f[i+1]*k[i]+b[i]; 26 } 27 for(int i=0;i<ls;i++) cnt[str[i]-'A']++; 28 double ans = 0; 29 for(int i=0;i<26;i++) ans += f[cnt[i]]*g[cnt[i]]; 30 printf("%.1lf ",ans); 31 } 32 33 int main(){ 34 scanf("%s",str); 35 work(); 36 return 0; 37 }