1. 程式人生 > >BZOJ 4318 OSU!

BZOJ 4318 OSU!

題面

題意

給出一串數,每個數字有a[i]的貢獻是’O’,這串數字的分數定義為每一段連續的O的長度的立方和,OXXOO的分數就是13+23=9,求期望分數。

做法

我的做法是考慮以每一個數為該段最後一個數產生的貢獻,dp時記三個數a,b,c分別表示這個數是O時,此時最後一段的長度,長度的平方,長度的立方的期望,轉移時只要根據下面兩式即可。
( x + 1

) 2 = x 2 + 2 x
+ 1 (x+1)^2=x^2+2*x+1
( x + 1 )
3 = x 3 + 3 x 2 + 3 x + 1 (x+1)^3=x^3+3*x^2+3*x+1

比較難以描述,程式碼比較好懂。

程式碼

#include<iostream>
#include<cstdio>
#define db double
#define N 100100
using namespace std;

int n;
db ans,num[N];
struct Num
{
	db sum,pf,lf;
}dp[N];

int main()
{
	int i,j;
	db p;
	cin>>n;
	for(i=1;i<=n;i++) scanf("%lf",&num[i]);
	for(i=1;i<=n;i++)
	{
		p=num[i];
		dp[i].sum=(dp[i-1].sum+1)*p;
		dp[i].pf=(1+dp[i-1].pf+2*dp[i-1].sum)*p;
		dp[i].lf=(1+dp[i-1].lf+3*dp[i-1].pf+3*dp[i-1].sum)*p;
		ans+=dp[i].lf*(1-num[i+1]);
	}
	printf("%.1f",ans);
}