1. 程式人生 > >【BZOJ】4318: OSU! 期望DP

【BZOJ】4318: OSU! 期望DP

給定 LG sed space $$ open IT con ont

【題意】有一個長度為n的01序列,每一段極大的連續1的價值是L^3(長度L)。現在給定n個實數表示該位為1的概率,求期望總價值。n<=10^5。

【算法】期望DP

【題解】後綴長度是一個很關鍵的量,設g[i]表示前i個的期望後綴長度。根據全期望公式,依賴於第i-1位為0或1:(以下所有公式最後省略+(1-ai)*0)

$$g[i]=a_i*(g[i-1]+1)$$

設f[i]表示前i個的期望長度,當第i-1位為1時,f[i]相對於f[i-1]的後綴多了[ (g[i-1]+1)^3 ] - [ g[i-1]^3 ]的代價,即:

$$f[i]=f[i-1]+a_i*(3*g[i-1]^2+3*g[i-1]+1)$$

等等,這沒有結束,只有加法和乘法滿足期望的線性,不包括乘方。通俗地說,期望的乘方不等於乘方的期望。

設g2[i]表示前i個的期望“後綴長度的平方”,同樣的g2[i]相對於g2[i-1]多了[ (g[i-1]+1)^2 ] - [ g[i-1]^2 ],即:

$$g^2[i]=a_i*(g^2[i-1]+2*g[i-1]+1)$$

復雜度O(n)。

技術分享圖片
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=100010;
double f[maxn],g[maxn],g2[maxn];
int n; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { double x; scanf("%lf",&x); g[i]=(g[i-1]+1)*x; g2[i]=(g2[i-1]+2*g[i-1]+1)*x; f[i]=f[i-1]+(3*g2[i-1]+3*g[i-1]+1)*x; } printf("%.1lf",f[n]); return 0; }
View Code

【BZOJ】4318: OSU! 期望DP