BZOJ 3450 Tyvj1952 Easy 期望DP

题目大意:给定一个OX序列,一些点未确定,连续len长度的O会得到len^2的收益,求期望收益值

令f[i]为第i个点的期望收益值,l[i]为第i个点的期望长度

如果一个点是'O' 那么l[i]=l[i-1]+1 f[i]=f[i-1]+(l[i]*2-1)

如果一个点是'X' 那么l[i]=0 f[i]=f[i-1]

如果一个点是'?' 那么l[i]=(l[i-1]+1)/2 f[i]=f[i-1]+(l[i]*2-1)

等等 好像有些问题- -

如果一个点长度为1那么增加的收益显然是(1*2-1) 长度为2那么增加的收益显然是(2*2-1)

可是如果长度为0那么增加的收益是(0*2-1)么?显然不是

实际上如果长度为0那么收益可以按照长度为0.5计算

那么最后一个递推式改成f[i]=f[i-1]+(l[i-1]+0.5)即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 300300
using namespace std;
int n;
char s[M];
double f[M],l[M];
//f[i]表示第i个点的期望得分
//l[i]表示第i个点的期望长度
int main()
{
	int i;
	cin>>n;
	scanf("%s",s+1);
	for(i=1;i<=n;i++)
	{
		switch(s[i])
		{
			case 'o':
				l[i]=l[i-1]+1;
				f[i]=f[i-1]+(l[i]+l[i]-1);
				break;
			case 'x':
				l[i]=0;
				f[i]=f[i-1];
				break;
			case '?':
				l[i]=(l[i-1]+1)/2.0;
				f[i]=f[i-1]+(l[i-1]+0.5);
				break;
		}
	}
	printf("%.4lf\n",f[n]);
	return 0;
}


你可能感兴趣的:(bzoj,期望DP,BZOJ3450)