首先我们设len[i]表示前i位,从第i位往前拓展,期望有多少个'o',那么比较容易的转移
len[i]=len[i-1]+1 s[i]='o'
len[i]=0 s[i]='x'
len[i]=(len[i-1]+1)/2 s[i]='?'
那么我们考虑,假设长度为a的连续'o',得分为n^2=(n-1)*n/2=Σ(2*i+1) (i=0..n-1),这样的转化可以满足递推的性质,设w[i]代表前i位的期望得分,那么可以有如下转移
w[i]=w[i-1] s[i]='x'
w[i]=w[i-1]+2*len[i-1]+1 s[i]='o' 这里累加的是len[i-1]保证了累加的数为0-n-1
w[i]=w[i-1]+(2*len[i-1]+1)/2 s[i]='?'
/************************************************************** Problem: 3450 User: BLADEVIL Language: C++ Result: Accepted Time:56 ms Memory:5492 kb ****************************************************************/ //By BLADEVIL #include <cstdio> #define maxn 300010 using namespace std; int n; char s; double w[maxn],len[maxn]; int main() { scanf("%d ",&n); for (int i=1;i<=n;i++) { scanf("%c",&s); if (s=='x') len[i]=0,w[i]=w[i-1]; if (s=='o') len[i]=len[i-1]+1,w[i]=w[i-1]+len[i-1]*2+1; if (s=='?') len[i]=(len[i-1]+1)/2,w[i]=w[i-1]+len[i-1]+0.5; } printf("%.4f ",w[n]); return 0; }