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


    【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
    ",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
    ",a);
    			printf("%lld",k);
    			for(int i=1;i<=ss;++i)putchar('-');putchar('
    ');
    			for(int i=1;i<=blk;++i)putchar(' ');
    			printf("%lld
    ",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;
    }
    
    
  • 相关阅读:
    安卓渗透测试环境搭建笔记
    spring boot Thymeleaf 模板注入 测试实践
    分析activity安全检测实践
    xposed的使用实践
    android组件安全测试实践
    Apache Dubbo Provider默认反序列漏洞复现实践(CVE-2020-1948)
    java设计模式--策略模式
    spring 发送email
    简单介绍
    有意义的礼物——英语小短文
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8427393.html
Copyright © 2020-2023  润新知