码迷,mamicode.com
首页 > 其他好文 > 详细

【Luogu1291】百事世界杯之旅(动态规划,数学期望)

时间:2018-02-07 19:51:19      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:out   algo   期望   www.   tput   clu   main   ring   post   

【Luogu1291】百事世界杯之旅(动态规划,数学期望)

题面

洛谷

题解

\(f[i]\)表示已经集齐了\(i\)个名字的期望

现在有两种方法:
先说我自己的:
\[f[i]=f[i-1]+1+(1-p)(1*p^1+2*p^2+....)\]
其中\(p=\frac{i-1}{n}\)
为什么,很简单
首先要多收集一个,期望\(+1\)是显然的
但是还可能一直买到了已经有的名字中的一个
\(p\)的概率多买一个
\(p^2\)的概率多买两个
这样无穷的算下去
然后对于后面那个式子
做两次错位相减(其实就是一个无穷级数)
推出
\[f[i]=f[i-1]+1+\frac{i-1}{n-(i-1)}\]
然后递推就行了

第二种方法:
\(fdf\)的方法(感觉这种方法也很强呀)
\(f[i]\)表示已经收集了\(i\)
收集到\(n\)个需要的期望
\[f[i]=\frac{i}{n}(f[i]+1)+\frac{n-i}{n}(f[i+1]+1)\]
\[\frac{n-i}{n}f[i]=\frac{n-i}{n}f[i+1]+1\]
\[f[i]=f[i+1]+\frac{n}{n-i}\]
初值:\(f[n]=0\)
倒着算即可

贴上我自己的代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
inline int read()
{
    RG int x=0,t=1;RG char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    if(ch=='-')t=-1,ch=getchar();
    while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    return x*t;
}
int n;
int ws(ll x)
{
    int ret=0;
    while(x)++ret,x/=10;
    return ret;
}
struct Num
{
    ll a,b;
    void easy()
        {
            ll d=__gcd(a,b);
            a/=d;b/=d;
        }
    void output()
        {
            easy();
            if(b==1){printf("%lld\n",a);return;}
            ll k=a/b;a-=k*b;
            int blk=ws(k),ss=max(ws(a),ws(b));
            for(int i=1;i<=blk;++i)putchar(' ');
            printf("%lld\n",a);
            printf("%lld",k);
            for(int i=1;i<=ss;++i)putchar('-');putchar('\n');
            for(int i=1;i<=blk;++i)putchar(' ');
            printf("%lld\n",b);
        }
}f[50];
Num operator+(Num a,Num b)
{
    ll d=a.b/__gcd(a.b,b.b)*b.b;
    return (Num){a.a*(d/a.b)+b.a*(d/b.b),d};
}
Num operator*(Num a,Num b)
{
    Num c=(Num){a.a*b.a,a.b*b.b};
    c.easy();
    return c;
}
int main()
{
    n=read();
    f[0]=(Num){0,1};
    for(int i=1;i<=n;++i)
    {
        f[i]=f[i-1]+(Num){1,1};
        f[i]=f[i]+(Num){i-1,n-i+1};
    }
    f[n].output();
    return 0;
}

【Luogu1291】百事世界杯之旅(动态规划,数学期望)

标签:out   algo   期望   www.   tput   clu   main   ring   post   

原文地址:https://www.cnblogs.com/cjyyb/p/8427393.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!