zoukankan      html  css  js  c++  java
  • 牛客练习赛 26 B题 烟花【DP】(经典)

    <题目链接>

    题目描述
    小a有$n$个烟花,每个烟花代表着互不相同的颜色,对于第$i$个烟花,它有$p_i$的概率点燃,现在小a要去点燃它们,他想知道产生颜色的期望个数 及 产生恰好产生$k$种颜色的概率。
    对于$100%$的数据$(n leq 10^5 ,k leq 2 imes 10^2)$输出均保留4位小数,若你的答案误差与std不超过$10^{-4}$即为正确
    解题分析:
    本题是比较经典的dp,$dp[i][j]$表示前i件物品中产生j件物品的概率,不难想到,状态转移方程为:$dp[i][j] = dp[i-1][j]*(1-p[i])+dp[i-1][j-1]*p[i]$;
    意思是:前$i$件物品中产生$j$个颜色的概率为前$(i-1)$个物品产生$j$个颜色*第$i$个物品不产生颜色的概率,加上前$(i-1)$件物品产生$(j-1)$种颜色*第i个物品产生颜色的概率。然后再用滚动数组优化成一维dp即可。

     
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5+10;
    double p[N];
    double dp[1010];    //实际上是dp[i][j],只不过下面用了滚动数组,意义是前i个物品产生j中颜色的概率
    
    int main(){
        int n,k;
        scanf("%d %d",&n, &k);
        double ans = 0;
        for(int i = 1; i <= n; i ++) scanf("%lf",&p[i]), ans += p[i];
        
        dp[0] = 1;
        for(int i = 1; i <= n; i ++){
            for(int j = k;j>=0;j--){
                dp[j] = dp[j]*(1-p[i])+dp[j-1]*p[i];
            }//前i个物品产生j种颜色的概率为,前i-1个物品产生 j种颜色的概率*第i个物品不产生颜色的概率加上前i-1个物品产生j-1个颜色的概率*第j个物品产生颜色的概率 
        }
    
        printf("%.4f
    %.4lf",ans,dp[k]);
        return 0;
    }

      

     
  • 相关阅读:
    cqyz oj | 单峰排列
    cqyz oj/uva 548 | 二叉树
    cqyz oj | 树网的核 | 树的直径
    cqyz oj | 树上的询问 | 最近公共祖先
    cqyz oj | 循环逆序对 | 逆序对 | 树状数组
    cqyz oj | 潜水比赛 | 贪心
    YOLO v3 & Pascal VOC数据集
    太阳爆发分类
    PPT制作
    anaconda
  • 原文地址:https://www.cnblogs.com/00isok/p/9608211.html
Copyright © 2011-2022 走看看