概率与期望做题笔记1

文章目录P1850 - [NOIP2016 提高组] 换教室P3802 - 小魔女帕琪P4550 - 收集邮票Coupon collector's problemP3239 - [HNOI2015]亚瑟王P3750 - [六省联考 2017] 分手是祝愿P3232 - [HNOI2013]游走P3830 - [SHOI2012]随机树整数概率公式P3412 - 仓鼠找sugar II待补P4284 - [SHOI2014]概率充电器CF749E - Inversions After ShuffleP185
摘要由CSDN通过智能技术生成

P1850 - [NOIP2016 提高组] 换教室

题目描述:

现在有 2 n 2n 2n 节课安排在 n n n 个时间段上。在第 i i i 个时间段上有内容相同的两节课分别在不同的教室 c i c_i ci d i d_i di 在进行,牛牛每节课预先被安排在 c i c_i ci 教室上课。

现在可以提出换教室的申请,对于第 i i i 个时间段,有 k i k_i ki 的概率成功换课到 d i d_i di 教室,并且各个换教室的申请之间都是独立的。现在可以一次性至多提出 m m m 个申请(即代表着不能根据某节课是否申请更换成功而做其他决定)。

牛牛所在的学校有 v v v 个教室, e e e 条道路,经过每条道路需要花费对应的时间,并且保证可以从学校之间两两教室互通。现在要求知道申请哪几门课可以使得期望的花费时间最小,求出这个最小值

1 ≤ n ≤ 2000 , 0 ≤ m ≤ 2000 , 1 ≤ v ≤ 300 , 0 ≤ e ≤ 90000 1 \leq n \leq 2000,0 \leq m \leq 2000,1 \leq v \leq 300,0 \leq e \leq 90000 1n2000,0m2000,1v300,0e90000

solution:

期望基础题。

期望产生于从一个教室走到另一个教室的过程,根据期望的线性可加性,我们要求的期望就是相邻时段之间的期望之和,考虑用 dp 得到最优解,设 f i , j , 0 / 1 f_{i,j,0/1} fi,j,0/1 代表前 i i i 个时段用了 j j j 次换教室资格,并且第 i i i 个教室 没申请/申请了 换教室资格的最小期望(因为我们转移的时候要考虑前后两个时段的教室的具体位置)

转移方程比较直观,即对于所有 f i , j , 1 f_{i,j,1} fi,j,1 的情况,我们需要讨论它是否成功更换,详细见代码

code:

#include <bits/stdc++.h>

using namespace std;

const int maxn=2077;

int n,m,v,e,c[maxn],d[maxn];
int g[305][305];
double k[maxn],f[maxn][maxn][2];

void floyd(){
   
    for(int k=1;k<=v;k++){
   
        for(int i=1;i<=v;i++){
   
            for(int j=1;j<=v;j++) g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
        }
    }
}

int main(){
   
    scanf("%d %d %d %d",&n,&m,&v,&e);
    for(int i=1;i<=n;i++) scanf("%d",&c[i]);
    for(int i=1;i<=n;i++) scanf("%d",&d[i]);
    for(int i=1;i<=n;i++) scanf("%lf",&k[i]);
    memset(g,0x3f,sizeof g);
    for(int i=1;i<=v;i++) g[i][i]=0;
    int u,v,w;
    for(int i=1;i<=e;i++){
   
        scanf("%d %d %d",&u,&v,&w);
        g[u][v]=g[v][u]=min(g[u][v],w);
    }
    floyd();

    for(int i=1;i<=n;i++){
   
        for(int j=0;j<=m;j++) f[i][j][0]=f[i][j][1]=1e18;
    }
    f[1][0][0]=f[1][1][1]=0;

    for(int i=2;i<=n;i++){
   
        for(int j=0;j<=min(i,m);j++){
   
            int c1=c[i],d1=d[i];
            int c2=c[i-1],d2=d[i-1];
            double w1=g[c1][c2];
            double w2=g[c1][d2]*k[i-1]+g[c1][c2]*(1-k[i-1]);
            double w3=g[d1][c2]*k[i]+g[c1][c2]*(1-k[i]);
            double w4=g[d1][d2]*k[i]*k[i-1]+g[d1][c2]*k[i]*(1-k[i-1])+g[c1][d2]*(1-k[i])*k[i-1]+g[c1][c2]*(1-k[i])*(1-k[i-1]);
            f[i][j][0]=min(f[i-1][j][0]+w1,f[i-1][j][1]+w2);
            if(j) f[i][j][1]=min(f[i-1][j-1][0]+w3,f[i-1][j-1][1]+w4);
        }
    }
    double ans=1e18;
    for(int i=0;i<=m;i++) ans=min(ans,min(f[n][i][0],f[n][i][1])); 
    printf("%.2f\n",ans);
    return 0;
}

P3802 - 小魔女帕琪

题目描述:

现在有 7 7 7 种属性的能量晶体,第 i i i 种晶体可以施放出属性为 i i i 的魔法,共有 a i a_i ai 个。每次施放魔法时,会等概率随机消耗一个现有的能量晶体,然后释放一个对应属性的魔法。如果连续施放的 7 7 7 个魔法的属性都各不相同,就能触发一次七重奏(无论这前 6 6 6 个魔法是否参与过之前的七重奏)。求触发七重奏的期望。

0 ≤ a i ≤ 1 0 9 , ∑ a i ≤ 1 e 9 0 \leq a_i \leq 10^9,\sum a_i \leq 1e9 0ai109,ai1e9

solution:

n = ∑ a i n = \sum a_i n=ai

首先题目问的实际上就是把这 n n n 个数放进一个空序列,然后总共 n − 6 n-6 n6 个长度为 7 7 7 的连续序列中序列元素各不相同的期望,考虑计算每一段的期望然后相加。

对于第一段来说,其出现七重奏的概率是: 7 ! ⋅ ∏ i = 1 7 a i n ( n − 1 ) ( n − 2 ) ( n − 3 ) ( n − 4 ) ( n − 5 ) ( n − 6 ) \frac {7! \cdot\prod_{i=1}^7a_i} {n(n-1)(n-2)(n-3)(n-4)(n-5)(n-6)} n(n1)(n2)(n3)(n4)(n5)(n6)7!i=17ai。( 7 7 7 种属性出现的顺序不同下的式子相同,所以乘以 7 ! 7! 7!

接着考虑第二段,也就是第 8 8 8 次随机释放得到七重奏的概率。

首先要知道前后魔法施放不互相影响,相当于第一次胡乱用掉一个能量晶体后从头再来,也就是条件概率。

那么我们只需要考虑第一次用的是哪个晶体,对应的 a i a_i ai 减少 1 1 1,也就是这样的式子:

7 ! × a 1 n × a 1 − 1 n − 1 × a 2 n − 2 × . . . × a 7 n − 7 7! \times \frac {a_1} n \times \frac {a_1-1} {n-1} \times \frac {a_2} {n-2} \times...\times \frac {a_7} {n-7} 7!×na1×n1a11×n2a2×...×n7a7 7 ! × a 2 n × a 2 − 1 n − 1 × a 1 n − 2 × . . . × a 7 n − 7 7! \times \frac {a_2} n \times \frac {a_2-1} {n-1} \times \frac {a_1} {n-2} \times...\times \frac {a_7} {n-7} 7!×na2×n1a21×n2a1×...×n7a7 . . . ... ...
把他们相加,化简后发现和第一段的概率相同,最终我们推广到所有 n − 6 n-6 n6 段,答案就是第一段的基础上在乘上 n − 6 n-6 n6

7 ! × ( n − 6 ) × a 1 n × a 1 − 1 n − 1 × a 2 n − 2 × . . . × a 7 n − 7 7! \times (n-6) \times \frac {a_1} n \times \frac {a_1-1} {n-1} \times \frac {a_2} {n-2} \times...\times \frac {a_7} {n-7} 7!×(n6)×na1×n1a11×n2a2×...×n7a7

P4550 - 收集邮票

题目描述:

现在有 n n n 种不同的邮票,现在要购买邮票,其中第 i i i 次需要支付 i i i 元,并且等概率的得到 n n n 种邮票中的任意一种,即 1 n \frac 1 n n1 的概率吗,现在求收集所有邮票的期望花费。

solution:

购买价格与购买次数相关,我们先从购买次数入手,设 f i f_i fi 代表已经收集 i i i 张邮票,要取完剩下邮票的期望次数, 显然 f n = 0 f_n=0 fn=0

分析一下,现在有 i n \frac i n ni 的概率取得重复的邮票,剩下概率得到新的邮票,那么转移方程: f i = i n ⋅ ( f i + 1 ) + n − i n ⋅ ( f i + 1 + 1 ) f_i=\frac i n \cdot (f_i+1)+\frac {n-i} n \cdot (f_{i+1}+1) fi=ni(fi+1)+nni(fi+1+1) 化简得到: f i = f i + 1 + n n − i f_i=f_{i+1}+\frac n {n-i} fi=fi+1+nin

接着我们重新回到上面,求期望花费。设 g i g_i gi 代表已经收集 i i i 张邮票,要取完剩下邮票的期望花费 g n = 0 g_n=0 gn=0

接着 g i = i n ⋅ ( g i + f i + 1 ) + n − i n ⋅ ( g i + 1 + f i + 1 + 1 ) g_i=\frac i n \cdot (g_i+f_i+1) + \frac {n-i} n \cdot (g_{i+1}+f_{i+1}+1) gi=ni(gi+fi+1)+nni(gi+1+fi+1+1) 化简得到: g i = i n − i f i + g i + 1 + f i + 1 + n n − i g_i=\frac i {n-i} f_i+g_{i+1}+f_{i+1}+\frac n {n-i} gi=niifi+gi+1+fi+1+nin

至于为什么是 f i + 1 f_i+1 fi+1 f i + 1 + 1 f_{i+1}+1 fi+1+1,因为我们是将后面取到的邮票费用+1,从后往前推,那么 f i f_i fi 的上一个状态是 f i + 1 f_{i+1} fi+1

code:

#include <bits/stdc++.h>

using namespace std;

const int maxn=1e4+50;

int n;
double f[maxn],g[maxn];

int main(){
   
    scanf("%d",&n);
    f[n]=g[n]=0;
    for(int i=n-1;i>=0;i--){
   
        f[i]=f[i+1]+n*1.0/(n-i);
        g[i]=i*1.0/(n-i)*f[i]+g[i+1]+f[i+1]+n*1.0/(n-i);
    }

    printf("%.2f\n",g[0]);
    return 0;
}

其实我们也可以不直接维护花费期望,我们如果知道收集所有邮票的期望次数 x x x,那么答案不就是每一步花费的和吗,也就是 ∑ i = 1 x = x 2 + x 2 \sum_{i=1}^x=\frac {x^2+x} 2 i=1x=2x2+x,那么我们只需要维护期望次数的平方即可

Coupon collector’s problem

关于上一个问题,其涉及到一个经典问题,及有 n n n 个物品,每次花费 1 1 1 的代价等概率 1 n \frac 1 n n1 的得到任一物品,求得到所有物品的期望花费。

方法1: 参考上一题,我们设 已经…还需要… 状态倒推即可

方法2: f i f_i fi 代表已经购买了 i i i 个物品的期望花费

考虑正推的期望,我们由 f i f_i fi 去推 f i + 1 f_{i+1} fi+1,那么当前已经有了 i i i 个物品,有 i n \frac i n ni 的概率重复得到已经有的物品

下一次得到不同物品的概率为 n − i n \frac {n-i} n nni,下两次得到不同物品的概率为 i n × n − i n \frac i n \times \frac {n-i} n ni×nni(忽略第一次就买到的情况),下 k k k 次得到不同物品的概率为 ( i n ) k − 1 × n − i n (\frac i n)^{k-1} \times \frac {n-i}n (ni)k1×nni

这里假设第 k k k 次就是无穷次,则此步的期望为: E = 1 × n − i n + 2 × i n × n − i n + 3 × ( i n ) 2 × n − i n + . . . + k × ( i n ) k − 1 × n − i n E= 1 \times \frac {n-i} n + 2 \times \frac i n \times \frac {n-i} n+3 \times (\frac i n)^2 \times \frac {n-i} n+...+k \times (\frac i n)^{k-1} \times \frac {n-i} n E=1×nni+2×ni×nni+3×(ni)2×nni+...+k×(ni)k1×nni

i n × E = 1 × i n × n − i n + 2 × ( i n ) 2 × n − i n + 3 × ( i n ) 3 × n − i n + . . . + k × ( i n ) k × n − i n \frac i n \times E= 1 \times \frac i n \times \frac {n-i} n + 2 \times (\frac i n)^2 \times \frac {n-i} n+3 \times (\frac i n)^3 \times \frac {n-i} n+...+k \times (\frac i n)^k \times \frac {n-i} n ni×E=1×ni×nni+2×(ni)2×nni+3×(ni)3×nni+...+k×(ni)k×

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值