HDU 5985 概率
Posted ( m Lweleth)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5985 概率相关的知识,希望对你有一定的参考价值。
n种硬币各有cnt[i]枚,每轮下其有p[i]概率保留,问各种硬币只有它存活到最后一轮的概率。
设k轮后i硬币存活概率$a[i][k]=(1-p^k_i)^{cnt[i]}$
则最后只有第i种硬币存活概率为$\sum\limits_{k=1}^{+\infty}{\sum\limits_{j=1,j!=i}^{cnt[i]}{((1-a[i][k])-(1-a[i][k+1])) \times a[j][k-1]}}$
设k为10000次足够了
/** @Date : 2017-10-06 16:06:03 * @FileName: HDU 5985 概率.cpp * @Platform: Windows * @Author : Lweleth ([email protected]) * @Link : https://github.com/ * @Version : $Id$ */ #include <bits/stdc++.h> #define LL long long #define PII pair #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; int cnt[15]; double p[15]; double a[15][100010]; double ans[15]; double fpow(double a, int n) { double res = 1.0; while(n) { if(n & 1) res *= a; a *= a; n >>= 1; } return res; } int main() { int T; cin >> T; while(T--) { MMF(a); MMF(ans); int n; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d%lf", cnt + i, p + i); if(n == 1) { printf("1.000000\n"); continue; } for(int i = 0; i < n; i++) { double tp = p[i]; for(int j = 1; j <= 10000; j++) { a[i][j] = fpow(1.0 - tp, cnt[i]); tp *= p[i]; } } for(int i = 0; i < n; i++) { ans[i] = 0.0; for(int j = 1; j < 9999; j++) { double t = 1.00; for(int k = 0; k < n; k++) { if(k == i) continue; else t *= a[k][j]; } ans[i] += t * ((1.0 - a[i][j]) - (1.0 - a[i][j + 1])); /*cout << ans[i] << " "; cout << t << " "; cout << ans[i] << endl;*/ } } for(int i = 0; i < n; i++) printf("%.6lf%s", ans[i], i==n-1?"\n":" "); } return 0; }
以上是关于HDU 5985 概率的主要内容,如果未能解决你的问题,请参考以下文章