UVA - 10288 Coupons(期望的性质)

题目链接


假设已经收集了 k k k个图案,那么拿到一个新图案的概率为 n − k n \frac{n-k}{n} nnk,根据期望的性质,概率为p的期望会在1/p次后发生,那么答案就是 ∑ i = 1 n n n − i \sum_{i=1}^{n}\frac{n}{n-i} i=1nnin

实际上LRJ在紫书上是手推证明了这个性质(说实话这个证明我看不懂):令 s = k / n s=k/n s=k/n,拿一个新的需要 t t t次的概率为 s t − 1 ( 1 − s ) s^{t-1}(1-s) st1(1s),期望为 E E E。因此需要的平均次数为 ( 1 − s ) ( 1 + 2 s + 3 s 2 + 4 s 3 + . . . ) = ( 1 − s ) ∗ E (1-s)(1+2s+3s^2+4s^3+...)=(1-s)*E (1s)(1+2s+3s2+4s3+...)=(1s)E,即 s ∗ E = ( s + 2 s 2 + 3 s 3 + 4 s 4 + . . . ) = E − ( 1 + 2 s + 3 s 2 + 4 s 3 + . . . ) s*E=(s+2s^2+3s^3+4s^4+...)=E-(1+2s+3s^2+4s^3+...) sE=(s+2s2+3s3+4s4+...)=E(1+2s+3s2+4s3+...),移项得:

( 1 − s ) ∗ E = 1 + s + s 2 + s 2 + . . . (1-s)*E=1+s+s^2+s^2+... (1s)E=1+s+s2+s2+...

根据等比数列的求和公式,得: ( 1 − s ) ∗ E = ( 1 − s t ) / ( 1 − s ) (1-s)*E=(1-s^t)/(1-s) (1s)E=(1st)/(1s),当 t t t趋向无穷大时,有:

( 1 − s ) ∗ E = 1 / ( 1 − s ) = n / ( n − k ) (1-s)*E=1/(1-s)=n/(n-k) (1s)E=1/(1s)=n/(nk),即答案为 ∑ k = 1 n n n − k \sum_{k=1}^{n}\frac{n}{n-k} k=1nnkn

注意输出格式

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <cstdio>
#include <string>
#include <bitset>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> P;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const ll INF=1e18;
const int Mod=1e9+7;
const int maxn=2e5+10;

ll gcd(ll a,ll b){
    return b==0?a:gcd(b,a%b);
}

void elim(ll &x,ll &y){
    ll a=x,b=y;
    ll g=gcd(a,b);
    x/=g,y/=g;
}

int getLen(ll x){
    int ans=0;
    while(x){
        ans++;
        x/=10;
    }
    return ans;
}

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n;
    while(~scanf("%d",&n)){
        if(n==1){
            printf("1\n");
            continue;
        }
        ll u=1,d=1;
        for(int i=2;i<=n;i++){
            u=u*i+d;
            d=d*i;
            elim(u,d);
            //cout<<u<<" "<<d<<endl;
        }
        u*=n;
        elim(u,d);
        if(d==1){
            printf("%lld\n",u);
            continue;
        }
        ll x=0,p=u/d,q=u%d;
        x+=p,u=q;
        int len1=getLen(x),len2=getLen(d);
        for(int i=0;i<=len1;i++) printf(" ");
        printf("%lld\n",u);
        if(x) printf("%lld ",x);
        for(int i=0;i<len2;i++) printf("-");
        printf("\n");
        for(int i=0;i<=len1;i++) printf(" ");
        printf("%lld\n",d);

    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值