1. 程式人生 > >洛谷P1291 [SHOI2002]百事世界杯之旅 [數學期望]

洛谷P1291 [SHOI2002]百事世界杯之旅 [數學期望]

def col 描述 copy \n als 第一個 上電 cin

  題目傳送門

百事世界杯之旅

題目描述

“……在2002年6月之前購買的百事任何飲料的瓶蓋上都會有一個百事球星的名字。只要湊齊所有百事球星的名字,就可參加百事世界杯之旅的抽獎活動,獲得球星背包,隨聲聽,更克赴日韓觀看世界杯。還不趕快行動!”

你關上電視,心想:假設有n個不同的球星名字,每個名字出現的概率相同,平均需要買幾瓶飲料才能湊齊所有的名字呢?

輸入輸出格式

輸入格式:

整數n(2≤n≤33),表示不同球星名字的個數。

輸出格式:

輸出湊齊所有的名字平均需要買的飲料瓶數。如果是一個整數,則直接輸出,否則應該直接按照分數格式輸出,例如五又二十分之三應該輸出為(復制到記事本):$5 \frac{3}{20}$第一行是分數部分的分子,第二行首先是整數部分,然後是由減號組成的分數線,第三行是分母。減號的個數應等於分母的為數。分子和分母的首位都與第一個減號對齊。

分數必須是不可約的。

輸入輸出樣例

輸入樣例#1:
2
輸出樣例#1:
3


  分析:

  很明顯的數學期望。

  首先我們設當前還需要收集$k$個球星,現在的裝態為$f(n,k)$,那麽轉移的方程就是:$f(n,k)=\frac {(n-k)*f(n,k)}{n}+\frac {k*f(n,n-k)}{n}+1$,因為很明顯我們收集到了$n-k$個球星,那麽抽到沒收集到的球星的概率為$\frac {k}{n}$,抽到收集到的球星的概率為$\frac {n-k}{n}$,後面的那個+1就是代表多買了一瓶飲料。然後把方程移項,得到:$f(n,k)=f(n,n-k)+\frac {n}{k}$。然後註意輸出就行了。

  Code:

//It is made by HolseLee on 25th July 2018
//Luogu.org P1291
#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll n,ans,m=1,ka;

inline ll gcd(ll x,ll y)
{
    return y==0?x:gcd(y,x%y);
}

inline ll get(ll x)
{
    ll ret=0;
    while(x){
        ret++;x/=10
; } return ret; } int main() { ios::sync_with_stdio(false); cin>>n; for(int i=n;i>=1;i--){ ans=ans*i+m*n; m*=i;ka=gcd(ans,m); ans/=ka;m/=ka; } ka=ans/m; ans%=m; if(ans==0) printf("%lld\n",ka); else { ll gi=get(ka),lu=get(m); for(int i=1;i<=gi;i++) printf(" "); printf("%lld\n",ans); if(ka>0) printf("%lld",ka); for(int i=1;i<=lu;i++) printf("-"); printf("\n"); for(int i=1;i<=gi;i++) printf(" "); printf("%lld\n",m); } return 0; }

洛谷P1291 [SHOI2002]百事世界杯之旅 [數學期望]