期望dp专题 SPOJ1026 Favorite Dice Uva12230Crossing Rivers (数学期望)

期望什么的没什么大概印象

靠做题一步一步来吧

先一道水题

 Kids and Prizes

题意:n个盒子里装有礼物,m个人随机选择礼物,选完之后空盒子放回
问选中的礼物数的期望。
m个人是独立的。
对于每个礼物不被人选中的概率为((n-1)/n)^m
那么不被选中的礼物数的期望就是 n*((n-1)/n)^m
所以答案就是 n-n*((n-1)/n)^m;

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int n,m;
double pow(double x,int y)
{
    int i;
    double sum=1;
    for(i=1;i<=y;i++)
      sum*=x;
    return sum;
}
int main()
{
    double cnt;
     double ans;
    while(~scanf("%d%d",&n,&m))
    {
     cnt=double(n-1)/n;
    ans=n-n*pow(cnt,m);
    printf("%.9lf\n",ans);
    }
    return 0;
}

  

SPOJ1026 Favorite Dice

题目大意

给你一个n个面的骰子,每个面朝上的几率相等,问每个面都被甩到的期望次数

题解

当然也可以用概率dp来推:

我们设f[i]表示还须i种数才满足每个面都出现一次所需要的期望次数。

显然f[n]=0,答案为f[0],所以为逆推。

又由于选第i个数后再选一个数与已经选过的数不同的概率为(ni)/n,相同为i/n

故f【i】=(f【i+1】+1)*((n-i)/n)【就是成功选出不同的,那就加1次再乘上概率】+(f【i】+1)*(i/n)【这个就是本身的转了一次没拿到不同的,同样是+1乘上概率】

化简可得到f[i] = f [i + 1] + n/(n - i);
同时f【n】=0;所以代码
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
int t;
double f[1005];
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        int n;
        scanf("%d",&n);
        memset(f,0,sizeof(f));
        f[n] = 0;
        for(int i = n - 1;i >= 0;i--)
        {
            f[i] = f[i + 1] + n / (n - (double)i);
        }
        printf("%0.2lf\n",f[0]);
     } 
     return 0;
}

Uva12230Crossing Rivers (数学期望)

题目大意:
有个人每天要去公司上班,每次会经过N条河,家和公司的距离为D,默认在陆地的速度为1,
给出N条河的信息,包括起始坐标p,宽度L,以及船的速度v。船会往返在河的两岸,人到达河岸时,
船的位置是随机的(往返中)。问说人达到公司所需要的期望时间。
思路:

1,过每条河最坏的情况是t=3*L/v; 即去的时候船刚刚走。
2,过没条河最优的情况是t=L/v;    即去的时候船刚刚来。
3,由于船是均匀发布的,符合线性性质,所以平均下来,过每条河的时间t=2*L/v。
#include<cstdio>
#include<cstdlib>
#include<iostream>
using namespace std;
int main()
{
    int n,D,dis,p,l,v,Case=0;
    double ans;
    while(~scanf("%d%d",&n,&D)){
        if(n==0&&D==0) return 0;
        dis=0;ans=0;
        while(n--){
            scanf("%d%d%d",&p,&l,&v);
            ans=ans+2.0*l/v;
            D-=l;
        }
        ans=ans+1.0*D;
        printf("Case %d: %.3lf\n\n",++Case,ans);
    }
    return 0;
}

 codeforces round 604 E题:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxx = 2e5+10;
const int mod = 998244353;
LL p[maxx],dp[maxx];
LL quick(LL a,LL b)
{
    LL res=1;
    while(b)
    {
        if(b&1)res=(res*a)%mod;
        b>>=1;
        a=(a*a)%mod;
    }
    return res;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&p[i]);
    //dp[i]=(dp[i-1]+1)*(pi/100)+(dp[i-1]+1+dp[i])*(1-pi/100)
    for(int i=1;i<=n;i++)
        dp[i]=(dp[i-1]+1)*100%mod*quick(p[i],mod-2)%mod;
    printf("%lld\n",dp[n]);
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/hgangang/p/12005866.html