「SHOI2002」「LuoguP1291」百事世界盃之旅(UVA10288 Coupons)(期望,輸出
阿新 • • 發佈:2018-11-04
題目描述
“……在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 intmain() 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 }