bzoj 3450 DP

  首先我们设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;
}
原文地址:https://www.cnblogs.com/BLADEVIL/p/3591544.html