HDU 1099 Lottery (求数学期望)
传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=1099
Lottery
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4319 Accepted Submission(s): 1921
Problem Description
Eddy's company publishes a kind of lottery.This set of lottery which are numbered 1 to n, and a set of one of each is required for a prize .With one number per lottery, how many lottery on average are required to make a complete set of n coupons?
Input
Input consists of a sequence of lines each containing a single positive integer n, 1<=n<=22, giving the size of the set of coupons.
Output
For each input line, output the average number of lottery required to collect the complete set of n coupons. If the answer is an integer number, output the number. If the answer is not integer, then output the integer part of the answer followed by a space and then by the proper fraction in the format shown below. The fractional part should be irreducible. There should be no trailing spaces in any line of ouput.
Sample Input
2
5
17
Sample Output
3
5
11 --
12
340463
58 ------
720720
Author
eddy
题目意思:
每次发行n张彩票,要买多少张才能集齐。
分析:
假如发行1张,买1次就集齐了。所以买1张。
假如发行2张,第一次买的序号是1,第二次买中剩下那张的概率是1/2,所以要买两张才能买到第二张,所以要买3张才能才能集齐。
假如发行3张,第一次发的序号是1,要买1张,第二次买中剩下的两张之一的概率是2/3,所以要买3/2张,第三次买剩中最后一张的概率是1/3,所以要买3张,所以要买5+1/2张。
假如发行n张,第一次买中没买过的概率是1,第二次是n-1/n,第三次是n-2/n,第n次是1/n,
而对应需要买的张数是第一次买1张,第二次买n/n-1张,第三次买n/n-2,第n次买n张,所以求的是n/n,n/n-1,……1/n的和。
假如发行2张,第一次买的序号是1,第二次买中剩下那张的概率是1/2,所以要买两张才能买到第二张,所以要买3张才能才能集齐。
假如发行3张,第一次发的序号是1,要买1张,第二次买中剩下的两张之一的概率是2/3,所以要买3/2张,第三次买剩中最后一张的概率是1/3,所以要买3张,所以要买5+1/2张。
假如发行n张,第一次买中没买过的概率是1,第二次是n-1/n,第三次是n-2/n,第n次是1/n,
而对应需要买的张数是第一次买1张,第二次买n/n-1张,第三次买n/n-2,第n次买n张,所以求的是n/n,n/n-1,……1/n的和。
所以就是求:n(1+1/2+1/3+......+1/n)
举个例子,当n=5时,第一张有用的概率为1,买一张就行了,第二张有用的概率为4/5,所以买5/4张彩票能买上对你有用的,一次类推,sum=1+5/4+5/3+5/2+5/1=11…5/12,
需要注意的就是格式问题:(这个很重要,w了几次)
结果是整数的话,直接输出整数
结果不是整数的话,分为两部分输出,一个整数,和一个真分数
格式请参考代码,讲起来太麻烦了。。。
code:
#include<bits/stdc++.h> using namespace std; typedef long long LL; #define max_v 25 struct node { LL molecule;//分子 LL Denominator;//分母 }; LL gcd(LL a,LL b)//最大公约数 { if(b==0) return a; return gcd(b,a%b); } LL lcm(LL a,LL b)//最小公倍数 { return a/gcd(a,b)*b; } LL numlen(LL x)//数字长度 { LL c=0; while(x) { x=x/10; c++; } return c; } node f(int n) { node p; p.molecule=1; p.Denominator=1; if(n==1) return p; for(LL i=2;i<=n;i++) { LL x=lcm(i,p.Denominator); p.molecule=p.molecule*(x/p.Denominator)+(x/i); p.Denominator=x; LL y=gcd(p.Denominator,p.molecule); p.Denominator=p.Denominator/y; p.molecule=p.molecule/y; // printf("fz=%I64d fm=%I64d 最小公倍数=%I64d\n",p.molecule,p.Denominator,x); } p.molecule=p.molecule*n; LL y=gcd(p.Denominator,p.molecule); p.Denominator=p.Denominator/y; p.molecule=p.molecule/y; return p; } int main() { int n; while(~scanf("%d",&n)) { node p=f(n); if(p.molecule%p.Denominator==0) printf("%I64d\n",p.molecule/p.Denominator); else { LL x=p.molecule/p.Denominator; p.molecule=p.molecule-(x*p.Denominator); LL y=gcd(p.Denominator,p.molecule); p.Denominator=p.Denominator/y; p.molecule=p.molecule/y; int l1=numlen(x); int l2=numlen(p.Denominator); for(int i=0;i<=l1;i++) printf(" "); printf("%I64d\n",p.molecule); printf("%I64d ",x); for(int i=1;i<=l2;i++) printf("-"); printf("\n"); for(int i=0;i<=l1;i++) printf(" "); printf("%I64d\n",p.Denominator); } } return 0; }
心之所向,素履以往
分类:
ACM
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南