链接:https://vjudge.net/problem/HDU-5985
思路:数学题,哎呀差一丢丢就自己做出来了,没发现有地方重复计算了。说一下思路,先算出前100天(100天之后基本不影响最后结果的精度了,可以忽略不计)每种硬币全部死亡的概率。然后开始枚举,某种硬币在某一天(1-100)成为幸运硬币的可能,将所有的天的概率加起来。注意为了避免重复,某一天成为幸运硬币的概率应该等于其他所有种类硬币全死概率×(自己当天存活-上一天存货概率)(即为在这一天活下来且下一天死亡的概率),这样保存枚举的那天就恰好是幸运硬币出现的那天,不会出现重复计算的可能,这一点没想到啊!!!!!!
代码:
#include<bits/stdc++.h>
using namespace std;
double p[10];
double pp[10][100];
int num[10];
double res[10];
int t,n;
int main(){
scanf("%d",&t);
while(t--){
memset(pp,0,sizeof(pp));
scanf("%d",&n);
memset(res,0,sizeof(res));
for(int i=0;i<n;i++)scanf("%d%lf",&num[i],&p[i]);
if(n==1)printf("1.000000\n");
else{
for(int i=0;i<n;i++){
for(int j=1;j<=100;j++){
pp[i][j] = pow(1-pow(p[i],j),num[i]);//某种硬币在第j天全部死亡的概率
}
}
for(int i=0;i<n;i++){
for(int j=1;j<=99;j++){
double ans = 1;
for(int k=0;k<n;k++){
if(k==i)continue;
ans*=pp[k][j];
}
res[i]+=(pp[i][j+1]-pp[i][j])*ans;//当天存活下一天死亡的概率*其他所有硬币死亡的概率
}
}
for(int i=0;i<n-1;i++){
printf("%.6f ",res[i]);
}
printf("%.6f\n",res[n-1]);
}
}
return 0;
}
网友评论