貌似就是道简单的DP题。。。恩!
令f[i]表示到第i位的期望分数,l[i]表示到第i位的期望连续'o'的长度
对于长度为l的连续'o',长度又增加1,则贡献增加(l + 1)2 - l2 = 2 * l + 1
如果第i位是'o',则
l[i] = l[i - 1] + 1, f[i] = f[i - 1] + (2 * l[i - 1] + 1) (后面的一个等式可以推广到'?'的情况)
如果第i位是'x',则
l[i] = 0, f[i] = f[i - 1]
如果第i位是'?',则有一半概率是'x',一半概率是'o'讨论一下即可
l[i] = (l[i - 1] + 1) / 2, f[i] = f[i - 1] + (2 * l[i - 1] + 1) / 2 = f[i - 1] + (l[i - 1] + 0.5)
于是就做完辣~
1 /************************************************************** 2 Problem: 3450 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:12 ms 7 Memory:1100 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 12 using namespace std; 13 typedef double lf; 14 const int Maxlen = 3e5 + 100; 15 16 int n; 17 lf f[2], l[2]; 18 19 char buf[Maxlen], *ch = buf; 20 int Len; 21 22 inline int read() { 23 int x = 0; 24 while (*ch < '0' || '9' < *ch) ++ch; 25 while ('0' <= *ch && *ch <= '9') 26 x = x * 10 + *ch - '0', ++ch; 27 return x; 28 } 29 30 int main() { 31 Len = fread(ch, 1, Maxlen, stdin); 32 buf[Len] = '\0'; 33 int i, now; 34 n = read(); 35 for (i = 1, now = 0; i <= n; ++i, ++ch) { 36 now = !now; 37 while (*ch != 'o' && *ch != 'x' && *ch != '?') ++ch; 38 if (*ch == 'o') 39 l[now] = l[!now] + 1, f[now] = f[!now] + (2 * l[!now] + 1); 40 else if (*ch == 'x') 41 l[now] = 0, f[now] = f[!now]; 42 else l[now] = (l[!now] + 1) / 2.0, f[now] = f[!now] + (l[!now] + 0.5); 43 } 44 printf("%.4lf\n", f[now]); 45 return 0; 46 }
(p.s. 突然觉得这表情好魔性'o' 'o' 'o' 'o')
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen