1. 程式人生 > >「SHOI2002」「LuoguP1291」百事世界盃之旅(UVA10288 Coupons)(期望,輸出

「SHOI2002」「LuoguP1291」百事世界盃之旅(UVA10288 Coupons)(期望,輸出

題目描述

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

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

輸入輸出格式

輸入格式:

 

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

 

輸出格式:

 

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

分數必須是不可約的。

 

輸入輸出樣例

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

題解

難點大概是輸出?

首先考慮一下拋開狗血輸出怎麼寫吧。

設$f[n,k]$為在$n$個裡面抽中了$k$個的期望購買量。

那麼在手上有$(k-1)$個時,

那麼$f[n,k]=f[n][k-1]+\frac{n}{n-k}$(抽中概率為$\frac{n-k}[n]$,期望為$1/p$)

所以遞推就行了。

輸出嘛,瞎幾巴搞搞,問題也不大。

就是要注意UVA的輸出比SHOI多了個空格QAQ肽毒了

 1 /*
 2 qwerta 
 3 P1291 [SHOI2002]百事世界盃之旅 Accepted 
 4 100
 5 程式碼 C++,0.67KB
 6 提交時間 2018-11-04 17:04:33
 7 耗時/記憶體 30ms, 684KB
 8 */
 9 #include<iostream>
10 #include<cstdio>
11 #include<cmath>
12 using namespace std;
13 #define LL long long
14 LL fz[37];
15 LL fm[37];
16 int
main() 17 { 18 int n; 19 scanf("%d",&n); 20 fm[0]=1; 21 for(int k=1;k<=n;++k) 22 { 23 //f[n][k]=f[n][k-1]+n/(n-k+1); 24 fm[k]=fm[k-1]*(n-k+1); 25 fz[k]=fz[k-1]*(n-k+1)+fm[k-1]*n; 26 for(int j=2;j<=1e3;++j) 27 { 28 while(fm[k]%j==0&&fz[k]%j==0) 29 { 30 fm[k]/=j; 31 fz[k]/=j; 32 } 33 } 34 } 35 if(fz[n]%fm[n]==0){cout<<fz[n]/fm[n];return 0;} 36 int z=fz[n]/fm[n]; 37 fz[n]%=fm[n]; 38 for(int i=0;i<=log10(z);++i) 39 cout<<" "; 40 cout<<fz[n]; 41 cout<<endl; 42 cout<<z; 43 for(int i=0;i<=log10(fm[n]);++i) 44 cout<<"-"; 45 cout<<endl; 46 for(int i=0;i<=log10(z);++i) 47 cout<<" "; 48 cout<<fm[n]; 49 return 0; 50 }