数学期望练习 ---- UVA10288[Coupons]
作为常年不会期望的蒟蒻 今天在看完各机房大佬上午模拟题T1之后 决定重新并认真学习数论门槛知识点 ---- 期望
前置:
期望 个人理解为 对于一个具有多种状态且每种状态自带权值的随机事件所期望得到的权值答案
在公式定义上 期望为每个子事件的权值乘上其概率的总和
即 :E(x) = ∑P(i)a(i) 其中 Pi表示为当前事件发生的概率 ai表示当前事件的权值
性质 :
1、期望具有线性无关可乘性 即 E(x) * E(y) = E(xy),xy互相独立
2、期望具有线性可加性 即E(x) + E(y) = E(x + y)
3、期望与概率的关系 :概率为P的事件 期望在1/P次后发生
OK进入正题
题目链接:
https://www.luogu.com.cn/problem/UVA10288
题意
每张彩票上有一个漂亮图案,图案一共n种,如果你集齐了这n种图案就可以召唤神龙兑换大奖。
现在请问,在理想(平均)情况下,你买多少张彩票才能获得大奖的?
n ≤ 33
输入输出样例
输入 #1
2 5 17
输出 #1
3
5
11 --
12
340463
58 ------
720720
首先 我们可以看出 这道题很毒瘤 同时 他的统计答案方式也很毒瘤
ok 我们来看题
先给定一个经典思路:
我们假设 我们已经集齐了k个图案
那么 我们想要得到剩下任何一个图案的概率是 (n - k) / n
根据性质三 我们期望在 n / (n - k) 次之后集齐剩下的所有图案
所以 我们的期望答案就是∑ n / (n - k) (k∈[0,n - 1])
这样一来 我们即已经解决了答案的问题
下面是如何输出这个答案
首先 输出带分数 我们可以先算出假分数形式的答案之后 再将其化简为带分数
那么怎么去做这个答案呢
首先我们先设一个分子son = 0,分母ma = 1;
为什么分子初始为0 分母初始为1呢
因为在我们统计的运算中 分子一直在加 只需要根据分母的扩张而成倍增长即可 所以只需要从0开始加就行
然而分母一直在乘 不断根据当前需要加上的项的分母去改变他的倍数 所以必须从1开始 才能满足一直乘
如此之后 我们就可以从0开始枚举k 得到当前的n - k,取它和当前ma的lcm(最小公倍数) 然后扩展双方的分子 然后进行运算 并让答案化简即可
最后输出部分 只需要提前处理出带分数中整数部分的长度和分母的长度 严谨分配空格和分割线就行
不赘述了 看代码吧
1 //November_Rain 出品 2 //T 暴力 3 //T 正解 4 #include <iostream> 5 #include <algorithm> 6 #include <cmath> 7 #include <cstdio> 8 #include <climits> 9 #include <cassert> 10 #include <cstring> 11 #include <cstdlib> 12 #include <cctype> 13 #include <iomanip> 14 #include <utility> 15 #include <set> 16 #include <map> 17 #include <list> 18 #include <stack> 19 #include <queue> 20 #include <deque> 21 #include <vector> 22 #include <bitset> 23 #include <ctime> 24 #define int long long 25 #define ll long long 26 #define ull unsigned long long 27 #define re register 28 #define mod1 998244353 29 #define mod2 1000000007 30 #define ls (p << 1) 31 #define rs ((p << 1) | 1) 32 #define lowbit(x) x & (-x) 33 #define gcd(a,b) __gcd(a,b) 34 #define mid ((l + r) >> 1) 35 #define pb(x) push_back(x) 36 #define rep(i,a,b) for(re int i(a);i <= b;++ i) 37 #define rrep(i,a,b) for(re int i(a);i >= b;i --) 38 using namespace std; 39 inline int read(){ 40 re int x = 0,f = 1; 41 re char ch = getchar(); 42 while(!isdigit(ch)){ 43 if(ch == '-') f = -1; 44 ch = getchar(); 45 } 46 while(isdigit(ch)){ 47 x = x * 10 + ch - '0'; 48 ch = getchar(); 49 } 50 return x * f; 51 } 52 //#define OJ 53 //#define debug 54 signed main(){ 55 #ifdef OJ 56 freopen(".in","r",stdin); 57 freopen(".out","w",stdout); 58 #endif 59 int n = 0; 60 int son = 0; 61 int ma = 0; 62 while(scanf("%lld",&n) != EOF){ 63 ma = 1; 64 son = 0; 65 rep(i,0,n - 1){ 66 int tmpma = n - i; 67 int lcm = tmpma * ma / gcd(tmpma,ma); 68 son *= lcm / ma; 69 son += n * (lcm / tmpma); 70 ma = lcm; 71 int g = gcd(son,ma); 72 son /= g; 73 ma /= g; 74 } 75 if(ma == 1){ 76 cout << son << endl; 77 } 78 else { 79 int cnt = 0; 80 while(son >= ma){ 81 son -= ma; 82 cnt ++; 83 } 84 int tmp = cnt; 85 int space = 0; 86 while(tmp >= 10){ 87 tmp /= 10; 88 space ++; 89 } 90 int tmp2 = space; 91 rep(i,1,space + 2) cout << " "; 92 cout << son << endl; 93 cout << cnt << " "; 94 tmp = ma; 95 space = 0; 96 while(tmp >= 10){ 97 tmp /= 10; 98 space ++; 99 } 100 rep(i,1,space + 1) cout << "-"; 101 cout << endl; 102 rep(i,1,tmp2 + 2) cout << " "; 103 cout << ma << endl; 104 } 105 } 106 #ifdef debug 107 printf("\nTime used = %lf", (double)clock() / CLOCKS_PER_SEC); 108 #endif 109 return 0; 110 }
‘Cuase nothing lasts forever, even cold November_rain.