zoukankan      html  css  js  c++  java
  • 算概率(dp,数论)

    链接:https://ac.nowcoder.com/acm/contest/3003/C
    来源:牛客网

    题目描述

    牛牛刚刚考完了期末,尽管牛牛做答了所有 n 道题目,但他不知道有多少题是正确的。
    不过,牛牛知道第 i 道题的正确率是 pi
    牛牛 想知道这 n 题里恰好有 0,1,…,n 题正确的概率分别是多少,对 109+7取模。
    对 109+7取模的含义是:对于一个 b≠0的不可约分数 a/b,存在 使得 b×q mod (109+7)=aq 即为 a/b 对 109+7取模的结果。

    输入描述:

    第一行,一个正整数 n 。
    第二行,n 个整数 p1,p2,…,pn,在模 109+7意义下给出。
    保证 1n2000。

    输出描述:

    输出一行 n+1个用空格隔开的整数表示答案(对 109+7取模)。

    输入

    1
    500000004

    输出

    500000004 500000004

    说明

    有 1 道题,做对的概率是 1/2 ( 1/2在模 109+7意义下为 500000004 )。

    先说一点:

    mod为109+7,为质数

    inv(b,mod) 表示b对mod的逆元,由费马小定理知b对mod的逆元即为bmod-2

    求(a/b)%mod即为求(a*inv(b,mod))%mod,即等于该题的p。

    long long fpow(long long a, long long b)
    {
        if (a == 0) return 0;
        long long ans = 1;
        for (; b; b >>= 1, a = (a % mod * a% mod) % mod)
            if (b & 1) ans = (ans % mod * a % mod) % mod;
        return ans;
    }
    LL inv(LL a,LL mo)
    {
        return fpow(a,mo-2)%mo;
    } 
    //求(a/b)%mod: printf("%lld
    ",a*inv(b,mod)%mod);

    另外注意到(a/b)%mod+(1- a/b)%mod = mod+1,由此可通过某事件概率求得其对立概率。

    该题总体来说还是用dp来做,只不过用概率%mod(即题中p)来代替原本的概率即可。

    dp[ i ][ j ] 表示前 i 道题做对 j 道的概率。

    转移时考虑第 j 道题是否做对,转移方程为:dp[ i ][ j ]=dp[ i-1 ][ j ]×(1−pi)+dp[ i-1 ][ j-1 ]×pi  

    时间复杂度 O(n2)

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 const int INF=0x3f3f3f3f;
    14 typedef long long LL;
    15 const LL mod=1e9+7;
    16 const int maxn=1e4+10;
    17 using namespace std;
    18 
    19 LL P[2005];//表示第i道题做对的概率
    20 LL dp[2005][2005];//dp[i][j]表示前i道题做对j道的概率
    21 
    22 int main()
    23 {
    24     #ifdef DEBUG
    25     freopen("sample.txt","r",stdin);
    26     #endif
    27 
    28     int n;
    29     scanf("%d",&n);
    30     for(int i=1;i<=n;i++)
    31         scanf("%lld",&P[i]);
    32     dp[0][0]=1;
    33     for (int i = 1; i <= n; i++)
    34     {
    35         dp[i][0] = dp[i - 1][0] * (mod + 1 - P[i]) % mod;
    36         for (int j = 1; j <= i; ++j)  //这个过程中求出来了有i题的情况下,做对0到i道题目的概率
    37             dp[i][j] = (dp[i - 1][j] * (mod + 1 - P[i]) + dp[i - 1][j - 1] * P[i]) % mod;
    38     }
    39     for(int i=0;i<=n;i++)
    40         printf(i==n?"%lld
    ":"%lld ",dp[n][i]);
    41 
    42     return 0;
    43 }

    -

  • 相关阅读:
    coffee.js
    domOperation.js
    ImmediateFunc.js
    callback.js
    array.js
    asynchronous.js
    addEventListener.js
    meta的日常设置
    11.11 双十一 前端教你一键领取天猫千张优惠券 (领前先想想有没有钱花这些优惠券)
    前端的最后是逻辑和数学
  • 原文地址:https://www.cnblogs.com/jiamian/p/12271768.html
Copyright © 2011-2022 走看看