UVA - 10288 Coupons (概率+递推)

Description

Problem F

Coupons

Input: standard input

Output: standard output

Time Limit: 2 seconds

Memory Limit: 32 MB

Coupons in cereal boxes are numbered 1 to n, and a set of one of each is required for a prize (a cereal box, of course). With one coupon per box, how many boxes on average are required to make a complete set ofn
coupons?

Input

Input consists of a sequence of lines each containing a single positive integern, 1<=n<=33, giving the size of the set of coupons. Input is terminated by end of file.

Output

For each input line, output the average number of boxes required to collect the complete set ofn 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 output.

Sample Input

2
5
17

Sample Output

3 
   5
11 --
   12
   340463
58 ------
   720720
题意:收集n个不同的优惠券的期望开箱次数
思路:设f[i]代表还有i个优惠券没有收集到的期望开箱次数,那么我们只要计算再没有取到的期望+上一个取到的期望+操作次数1,即f[i]=(n-i)/n*f[i]+i/n*f[i+1]+1,移项后是
f[i] = ((n-i)/n*f[i+1]+1)/((n-i)/n),然后就是一个分数计算的模板了
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 50; 

struct fraction {
	long long numerator; // 分子
	long long denominator; // 分母
	fraction() {
		numerator = 0;
		denominator = 1;
	}
	fraction(long long num) {
		numerator = num;
		denominator = 1;
	}
	fraction(long long a, long long b) {
		numerator = a;
		denominator = b;
		this->reduction();
	}

	void operator = (const long long num) {
		numerator = num;
		denominator = 1;
		this->reduction();
	}

	void operator = (const fraction &b) {
		numerator = b.numerator;
		denominator = b.denominator;
		this->reduction();
	}

	fraction operator + (const fraction &b) const {
		long long gcdnum = __gcd(denominator, b.denominator);
		fraction tmp = fraction(numerator*(b.denominator/gcdnum) + b.numerator*(denominator/gcdnum), denominator/gcdnum*b.denominator);
		tmp.reduction();
		return tmp;
	}

	fraction operator + (const int &b) const {
		return ((*this) + fraction(b));
	}

	fraction operator - (const fraction &b) const {
		return ((*this) + fraction(-b.numerator, b.denominator));
	}

	fraction operator - (const int &b) const {
		return ((*this) - fraction(b));
	}

	fraction operator * (const fraction &b) const {
		fraction tmp = fraction(numerator*b.numerator, denominator * b.denominator);
		tmp.reduction();
		return tmp;
	}

	fraction operator * (const int &b) const {
		return ((*this) * fraction(b));
	}

	fraction operator / (const fraction &b) const {
		return ((*this) * fraction(b.denominator, b.numerator));
	}

	void reduction() {
		if (numerator == 0) {
			denominator = 1;
			return;
		}
		long long gcdnum = __gcd(numerator, denominator);
		numerator /= gcdnum;
		denominator /= gcdnum;
	}
	void print() {
		if (denominator == 1) printf("%lld\n", numerator);
		else {
			long long num = numerator/denominator;
			long long tmp = num;
			int len = 0;
			while (tmp) {
				len++;
				tmp/=10;
			}

			for (int i = 0; i < len; i++) printf(" ");
			if (len != 0) printf(" ");
			printf("%lld\n",numerator%denominator);

			if (num != 0) printf("%lld ", num);
			tmp = denominator;
			while (tmp) {
				printf("-");
				tmp/=10;
			}
			puts("");

			for (int i = 0; i < len; i++) printf(" ");
			if (len != 0) printf(" ");
			printf("%lld\n",denominator);
		}
	}
} f[maxn];

int main() {
	int n;
	while (scanf("%d", &n) != EOF) {

		f[n] = 0;
		for (int i = n-1; i >= 0; i--)
			f[i] = (fraction(n-i, n) * f[i+1] + 1) / fraction(n-i, n);

		f[0].print();
	}
	return 0;
}

时间: 2024-07-31 10:37:14

UVA - 10288 Coupons (概率+递推)的相关文章

UVA 10288 - Coupons(概率递推)

UVA 10288 - Coupons 题目链接 题意:n个张票,每张票取到概率等价,问连续取一定次数后,拥有所有的票的期望 思路:递推,f[i]表示还差i张票的时候期望,那么递推式为 f(i)=f(i)?(n?i)/n+f(i?1)?i/n+1 化简后递推即可,输出要输出分数比较麻烦 代码: #include <cstdio> #include <cstring> #include <cmath> long long gcd(long long a, long lon

UVA 11021 - Tribles(概率递推)

UVA 11021 - Tribles 题目链接 题意:k个毛球,每个毛球死后会产生i个毛球的概率为pi,问m天后,所有毛球都死亡的概率 思路:f[i]为一个毛球第i天死亡的概率,那么 f(i)=p0+p1f(i?1)+p2f(i?1)2+...+pnf(i?1)n 然后k个毛球利用乘法定理,答案为f(m)k 代码: #include <stdio.h> #include <string.h> #include <math.h> const int N = 1005;

uva 10288 - Coupons(概率)

题目链接:uva 10288 - Coupons 题目大意:给定n,为有n中兑换卷,现在每开一次箱子,就能等概率的获得其中的一种兑换卷.问说平均情况下需要开多少个箱子才能集齐n种兑换卷. 解题思路:dp[i]表示还有i种没获得,dp[i]=n?in?dp[i]+in?dp[i?1]+1 ===>dp[i]=dp[i?1]+ni #include <cstdio> #include <cstring> #include <algorithm> using names

Uva 11021-Tribles(概率+递推)

题目链接:点击打开链接 题意:k只麻球,每活一天就会死亡,但第二天可能会生一些麻球,具体是 生i个麻球的概率为pi ,求m天后所有麻球都死亡的概率. 思路:考虑全概率公式,求k只麻球m天后全死亡 ,因为死亡是独立事件,应用乘法 ,ans= f[m] ^k ,f[m] 为一只麻球m天后均死亡的概率.对于第i天, f[i]=p0+p1*f[i-1]^1 +p2*f[i-1]^2 +...p(n-1)*f[i-1]^(n-1) (就是让i-1天所有的出生的麻球全部死亡,那么第i天麻球就没了..) 最终

UVa 557 Burger (概率+递推)

题意:有 n 个牛肉堡和 n 个鸡肉堡给 2n 个客人吃,在吃之前抛硬币来决定吃什么,如果剩下的汉堡一样,就不用投了,求最后两个人吃到相同的概率. 析:由于正面考虑还要要不要投硬币,太麻烦,所以我们先求最后两人吃到不同的概率即可,再用 1 减去就OK. 假设最后两个人吃的不一样,那么前 n-2 个人吃的肯定是 n/2 -1个牛肉堡和n/2-1 个鸡肉堡,根据排列组合可知,概率应该是C(n-2, n/2-1) * (0.5)^(n-2). 这就是公式,然而这个并不好算,很可能超时,所以我们再把第

UVA 1541 - To Bet or Not To Bet(概率递推)

UVA 1541 - To Bet or Not To Bet 题目链接 题意:这题题意真是神了- -,看半天,大概是玩一个游戏,开始在位置0,终点在位置m + 1,每次扔一个硬币,正面走一步,反面走两步,走到的步上有4种情况: 1.向前走n步 2.向后走n步 3.停止一回合 4.无影响 问能在t次机会内,走到终点m + 1(如果跃过也算走到了)的概率,大于0.5,等于0.5,小于0.5对应不同输出 思路:题意懂了就好办了,其实就是递推就可以了dp[i][j]表示第i次机会,落在j步的概率,然后

UVA 11427 - Expect the Expected(概率递推期望)

UVA 11427 - Expect the Expected 题目链接 题意:玩一个游戏,赢的概率p,一个晚上能玩n盘,如果n盘都没赢到总赢的盘数比例大于等于p,以后都不再玩了,如果有到p就结束 思路:递推,dp[i][j]表示玩i盘,赢j盘的概率,那么一个晚上玩了n盘小于p的概率递推式为: dp(i,j)=dp(i?1,j)?(1?p)+dp(i?1,j?1)?p 总和为Q=dp(n,0)+dp(n,1)+...+dp(n,x)(x/n<p) 那么每个晚上失败的概率Q就求出来了,那么平均玩的

uva 1478 - Delta Wave(递推+大数+卡特兰数+组合数学)

题目链接:uva 1478 - Delta Wave 题目大意:对于每个位置来说,可以向上,水平,向下,坐标不能位负,每次上下移动最多为1, 给定n问说有多少种不同的图.结果对10100取模. 解题思路:因为最后都要落回y=0的位置,所以上升的次数和下降的次数是相同的,并且上升下降的关系满足出栈入栈的关系.即卡特兰数. 所以每次枚举i,表示有i个上升,i个下降,用组合数学枚举出位置,然后累加求和. C(2?in)?f(i)=C(2?i?2n)?f(i?1)?(n?2?i+1)?(n?2?i+2)

【UVA】12034-Race(递推,组合数打表)

递推公式,假设第一名有i个人并列,那么: f[n] = C(n,i) * f[n - i]; 打出1 ~ 1000的所有组合数,之后记忆化搜索,需要打表. 14026995 12034 Race Accepted C++ 0.032 2014-08-12 11:47:47 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<vector&g

UVA - 620Cellular Structure(递推)

题目:UVA - 620Cellular Structure(递推) 题目大意:只能给出三种细胞的增殖方式,然后给出最后细胞的增殖结果,最后问你这是由哪一种增殖方式得到的.如果可以由多种增殖方式得到,就输出题目中列出来的增殖方式靠前的那种. 解题思路:也是递推,细胞长度长的可以由细胞长度短的推得,并且这里第一种只能是长度为1的细胞才有可能,所以判断的时候可以3个判断,看能否与上面的增殖结果匹配,可以的话就记录下来,以后的长串就是由这样的短串再加上两个细胞继续往后推. 例如: BAABA 将A变为