8.13 期望题目整理

海亮回来快一个月了才开始写博客 今天整理一下最近写的题目;

最近写了一些期望 还有一些图论,dp,和一些乱七八糟的题目;

稍微整理一下思路,

对于期望 我的理解不是特别明白 因为我仅限于做过的几道题目,但是其中仍然有些回味起来不是很懂,只能说慢慢来了嗷;

不过 如果我们把握一个公式,概率和取的值乘起来然后求累和的方法求期望,是可以解决一部分题目的;

至于为什么期望总是倒退,我觉得是和我们设得状态有关的,因为有时候我们设得状态都是当前为什么,距离要满足题意还需多少天(计量单位,不限);

看几个例子;

过河

说不上特别像期望,因为当时手推了一下样例,算出来了答案,然后模拟一边就过了,后来思考了一下,因为这个题的情况很多,所以我们可以考虑两种极端情况,他们已经是等概率的

第一种,刚到,船和人一起走,此时是L,第二种,刚到,船刚走,人需等待穿回来再走,此时是3L,所以总的期望是2L/v+走路面的距离;对于其他情况,我们都可以找到满足和为前者的情况;

#include<bits/stdc++.h>
using namespace std;
int n,d,p,l,v;
int main() {
    int ca=0;
    while(cin>>n>>d,d) {
        double ans=0;
        for(int i=1;i<=n;i++) {
            cin>>p>>l>>v;
            d-=l;
            ans+=2.0*l/v;
        }
        printf("Case %d: %.3lf\n\n",++ca,ans+d);
    }
    return 0;
}
View Code

收集邮票

介绍一下这一种经典模型,也成购物券收集问题;

问的形式大概是:有n个券,每天发一张(随意),求集齐所有券的期望天数;

还有一种就是:一个长1m的路段,雨滴是1cm,求覆盖所有地面期望雨滴数量;

这样我们转换一下,1m的路段看成100张券,雨滴看成一张券,所以模型转化;

对于这种题目,我们一般设得状态F[i]表示当前集齐i-1张还需集齐第i张得期望;

随机变量的和的期望等于这些随机变量期望之和

对于这个问题,我们需要把要求的期望分解为若干个随机变量的和。

(E(X1+X2)=E(X1)+E(X2), 当 X1, X2相互独立时)

设随机变量S表示收集到所有券所需的最少天数, 我们用Xi表示收集到(i-1)种优惠券后,还需要多少天才能收集到第i种优惠券。

X1表示收集到第一种优惠券所需天数,显然X1=1

我们来算X2,收集到第一种后,除了第一种的优惠券,其他任何一种都可以算第二种了,从而,他每天出现的概率为n-1/n,进而期望天数为n/n-1;

类似X3的期望为n/n-2;

我们有S=X1+X2+...Xn,

E(S)=E(X1)+E(X2)+...+E(Xn)。

类似的我们求下和就是答案,其实上面的式子考虑积分化简,但是我不清楚为什么直接考log是错的,算了我们还是循环吧;

其实为什么一件事情概率成功是p,那么期望是1/p的证明还是比较清楚地,证明方法很多,我自己推过了其中一种,大家可以自己理解一下;

#include<bits/stdc++.h>
template<typename T>inline void read(T &x) {
    x=0;
    T f=1,ch=getchar();
    while (!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}
double ans,cnt;
int n,x;
int main() {
    read(n); 
    for(int i=1;i<=n;++i) {
        read(x);
        ans=0;cnt=x;
        for(int j=x;j>=1;--j)ans+=cnt/j;    
        printf("%.2lf\n",ans);
    }
    return 0;
}
View Code

上电梯

把握一点期望等于概率乘上所取值求累和;

所以我们这个题设状态为概率;注释都在代码里;还有一种直接求期望的,我不是很明白,我不清楚拿期望乘合不合适,有兴趣去查另一种题解8;

 

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &x) {
    x=0;
    T f=1,ch=getchar();
    while (!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}
const int N=2010,T=2010;
double f[N][T];//f[i][j]表示在第i秒,电梯上有j个人的概率; 
int n,t;
double p,ans;
int main() {
    read(n);cin>>p; read(t);
    f[0][0]=1;//在第0时刻电梯上有0个人的概率为1; 
    for(int i=1;i<=t;i++) {
        for(int j=0;j<=n;j++)
            if(j==0) f[i][j]=(1-p)*f[i-1][j];//考虑两种极端情况; 
            else if(j==n) f[i][j]=f[i-1][j]+p*f[i-1][j-1];//
            else f[i][j]=(1-p)*f[i-1][j]+p*f[i-1][j-1]; 
    }
    for(int i=1;i<=n;i++)
        ans+=f[t][i]*i;
    printf("%.12lf\n",ans);
    return 0;
} 

 

OSU

写完就很迷,暂时不是很明白,回来补坑,代码很好写;

//p[i]*(x+1)^3=(x^3+1+3x^2+3x)*p[i]//f[i]=(f[i-1]+3*x^2+3*x+1); 
//f[i-1]=x^3; 
//因为期望线性,所以考虑维护前缀和,应该是维护x^2,x的期望,没想清楚 
//期望的和等于和的期望;
//失败是对答案没有影响的,因为贡献为0,只考虑成功 
//E1,E2维护一下hh 
#include<bits/stdc++.h>
using namespace std;
int n;
const int N=100010;
double E1[N],E2[N],p[N],f[N];
int main() {
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>p[i];
    for(int i=1;i<=n;i++) {
        E1[i]=(E1[i-1]+1)*p[i];
        E2[i]=(E2[i-1]+2*E1[i-1]+1)*p[i];
        f[i]=f[i-1]+(3*(E1[i-1]+E2[i-1])+1)*p[i];
    } 
    printf("%.1lf\n",f[n]);
    return 0;
} 

奖励关

是一道状压dp+期望;

F[i][s]表示当前进行了i-1轮,然后当前状态为S时,从第i轮到第K轮时期望最高得分,乘上概率1/n就是期望得分了;

对于转移,有取或者不取两种情况,

如果S包含的状态满足取第k种宝物的条件,则可以取或不取。不取则为f[i+1][S],取则为f[i+1][S|(1<<k-1)]+ck

所以此时f[i][S]+=max(f[i+1][S],f[i+1][S|(1<<k-1)]+ck)

2、如果S包含的状态不满足取第k种宝物的条件,则不能取,即f[i][S]+=f[i+1][S]

所要求的答案就是f[1][0];

#include<bits/stdc++.h>
using namespace std;
template<typename T>inline void read(T &x)
{
    x=0;
    register int f=1;
    register char ch=getchar();
    while (!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
    while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
    x*=f;
}
const int N=150;
const int M=1<<16; 
int K,n,x,b[N],a[N];
double f[N][M];
int main() {
    read(K); read(n);
    for(int i=1;i<=n;i++) {
        read(a[i]);
        read(x);
        while(x) {
            b[i]=b[i]|(1<<(x-1));//第i种的必选x,将x位为1; 
            read(x);
        }
    }
    for(int i=K;i>=1;--i) {
        for(int j=0;j<(1<<n);j++) {
            for(int k=1;k<=n;k++) {
                if((j&b[k])==b[k]) f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(k-1))]+a[k]);
                else f[i][j]+=f[i+1][j];
            }
            f[i][j]/=n;
        }
    }
    printf("%.6lf\n",f[1][0]);
    return 0;
}

刚准备提交发现自己还是不会期望,我以后再来填坑,真是让人自闭;

 

posted @ 2019-08-13 09:53  Tyouchie  阅读(515)  评论(2编辑  收藏  举报