zoukankan      html  css  js  c++  java
  • P1654 OSU! 期望DP

    # P1654 OSU! 期望DP
    
    ## 题意
    
    一个$01$串中每个长度为$X$的全1子串可以贡献$X^3$的分数。
    
    每次有$p_i$的概率在这一位出现$1$,求期望分数
    $$
    N leq 10^5
    $$
    
    ## 分析
    
    考虑3次的贡献,先从一次算起
    
    $a[i]$表示到第$i$位的长度为$1$的期望长度是多少
    $$
    a[i] = (a[i - 1] + 1)cdot p[i]
    $$
    拓展到二次
    $$
    b[i] = (b[i - 1] + 2 cdot a[i-1]+1)cdot p[i]
    $$
    拓展到三次
    $$
    f[i] = (f[i-1]+3cdot b[i-1]+3cdot a[i-1]+1)cdot p[i]
    $$
    由于这只是当前位的长度,还需要考虑当前位没有填$1$带来的贡献
    
    因此
    $$
    f[i] = (f[i-1]+3cdot b[i-1]+3cdot a[i-1]+1)cdot p[i] + f[i-1]cdot(1-p[i])\
    =f[i-1]+(3cdot b[i-1]+3cdot a[i-1] + 1)cdot p[i]
    $$
    维护这三个值即可
    
    ## 代码
    
    ```c++
    #include <bits/stdc++.h>
    #define pb push_back
    #define fi first
    #define se second
    #define eps 1e-8
    #define equals(a,b) fabs(a-b) < eps
    using namespace std;
    const int maxn = 1e5 + 5;
     
    int rd(){
    	int x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9'){
    		if(ch == '-') f = -1;
    		ch = getchar(); 
    	} 
    	while(ch >= '0' && ch <= '9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	} 
    	return x * f;  
    }
    
    
    double p[maxn];
    double a[maxn],b[maxn],f[maxn];
    
    int main(){
    	int n = rd();
    	for(int i = 1;i <= n;i++)
    		scanf("%lf",&p[i]);
    	for(int i = 1;i <= n;i++){
    		a[i] = (a[i - 1] + 1) * p[i];
    		b[i] = (b[i - 1] + 2 * a[i - 1] + 1) * p[i];
    		f[i] = f[i - 1] + (3 * b[i - 1] + 3 * a[i - 1] + 1) * p[i];		
    	}
    	printf("%.1f",f[n]);
    } 
    
  • 相关阅读:
    C#中Equals和= =(等于号)的比较)(转载)
    C# 控制台应用程序输出颜色字体
    c#获取当前运行程序所在的目录
    java环境配置
    c#随机产生颜色
    Git学习
    git删除所有提交历史记录
    git忽略项gitegnore配置
    不搭建git服务器对git仓库进行局域网内共享多人合作开发项目
    搭建Git服务器-SCM-Manager
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14390867.html
Copyright © 2011-2022 走看看