UVA - 10288 Coupons
题形:概率DP
题意:收集齐n个不同的优惠卷的期望开箱次数。(开一次箱子会等概率的得到其中一张优惠卷)
思路:
期望递推法。
正常做就行。就是分数输出麻烦了点。
e[i] = i/n(e[i]+1) + (n-i)/n(e[i+1]+1)
然后移项,递推就行了。
代码:
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 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); } //printf("%lld/%lld\n", numerator, denominator); } }; fraction e[N]; int main() { int n; while (scanf("%d", &n) != EOF) { e[n] = 0; for (int i = n-1; i >= 0; i--) { e[i] = (fraction(i,n) + fraction(n-i,n)*(e[i+1]+1)) / fraction(n-i,n); } e[0].print(); } return 0; }
posted on 2014-03-07 16:15 ShineCheng 阅读(333) 评论(0) 编辑 收藏 举报