UVa 10288 - Coupons(数学期望 + 递推)

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1229

 

题意:

大街上到处在卖彩票,一元钱一张。购买撕开它上面的锡箔,你会看到一个漂亮的图案。
图案有n种,如果你收集到所有n(n≤33)种彩票,就可以得大奖。
请问,在平均情况下,需要买多少张彩票才能得到大奖呢?如n=5时答案为137/12。

 

分析:

已有k个图案,令s=k/n,拿一个新的需要t次的概率:(s^(t-1))(1-s);
因此平均需要的次数为(1-s)(1 + 2s + 3s^2 + 4s^3 + …) = (1-s)E,
而sE = s + 2s^2 + 3s^3 + … = E-(1+s+s^2+…),移项得(1-s)E = 1+s+s^2+… = 1/(1-s) = n/(n-k)
换句话说,已有k个图案:平均拿n/(n-k)次就可多搜集一个,所以总次数为:n(1/n+1/(n-1)+1/(n-2)+…+1/2+1/1)

 

代码:

 1 import java.io.*;
 2 import java.util.*;
 3 
 4 public class Main {
 5     Scanner cin = new Scanner(new BufferedInputStream(System.in));
 6     
 7     long gcd(long a, long b) {
 8         return b == 0 ? a : gcd(b, a%b);
 9     }
10     
11     long lcm(long a, long b) {
12         return a / gcd(a,b) * b;
13     }
14     
15     int len(long v) {
16         int res = 0;
17         do { v /= 10;  res++; } while(v > 0);
18         return res;
19     }
20     
21     void printCh(char c, int x) {
22         while(x --> 0) System.out.print(c);
23     }
24     
25     void output(long a, long b, long c) {
26         if(b == 0) { System.out.println(a);  return; }
27         printCh(' ', len(a)+1);  System.out.println(b);
28         System.out.print(a + " ");  printCh('-', len(c)); System.out.println();
29         printCh(' ', len(a)+1);  System.out.println(c);
30     }
31     
32     void MAIN() {
33         while(cin.hasNext()) {
34             int n = cin.nextInt();
35             long b = 0, c = 1;
36             for(int i = 2; i <= n; i++) c = lcm(c, i);
37             for(int i = 0; i < n; i++) b += c / (n-i) * n;
38             output(b/c, b%c/gcd(b%c,c), c/gcd(b%c,c));
39         }
40     }
41     
42     public static void main(String args[]) { new Main().MAIN(); }
43 }

 

posted @ 2018-08-30 18:56  Ctfes  阅读(141)  评论(0编辑  收藏  举报