2016年ACM/ICPC青島賽區 D題(數學推導)
阿新 • • 發佈:2018-11-11
題意:給你n(n<=10)種硬幣,每種硬幣有a[i]個。對一枚硬幣,每操作一次,硬幣留下的概率為p[i]。
求進行若干次操作後每種硬幣留下的概率(題目要求n組輸出,每組輸出只留下這種硬幣的概率)。保留六位小數。
思路:沒想到居然這麼簡單。。。關鍵是沒想到操作100次以後就近似為0了,所以我們只考慮操作100次以內的情況。
硬幣的概率都是單獨的,所以我們只需要計算一個硬幣的概率情況即可。
設die[i][k]表示第i種硬幣在第k次全部被拋棄的概率,易得。用live[i][k]表示第i種硬幣在第k次至少有一個存活的概率就是1−die[i][k]。
最後計算就比較簡單了,。
程式碼:
#include <bits/stdc++.h> using namespace std; const int maxn=20; int a[maxn],n; double p[maxn]; double die[maxn][110],live[maxn][110]; int main() { int T,cas=1; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%lf",&a[i],&p[i]); } if(n==1) {puts("1.000000");continue;} for(int i=1;i<=n;i++) for(int k=0;k<=100;k++) { die[i][k]=pow(1.0-pow(p[i],k),a[i]); live[i][k]=1.0-die[i][k]; } for(int i=1;i<=n;i++) { double ans=0; for(int k=1;k<=100;k++) { double tmp=1; for(int j=1;j<=n;j++) if(j!=i)tmp*=die[j][k]; ans+=(live[i][k]-live[i][k+1])*tmp; } printf("%.6lf%c",ans,i==n?'\n':' '); } } return 0; }