题目大意:做一个烟花花费n分钟,把做的所有烟花放掉需要m分钟。每次可以选择做烟花,或者把所有的烟花放掉。
每个烟花成功燃放的概率为p*0.0001,一旦有烟花成功燃放就停止。问按最优策略,当有烟花成功燃放时,经过时间期望的最小值。
题解:假设做k次烟花再全部放掉是最优策略。
(为什么不能做5次烟花再全部放掉,再做6次烟花全部放掉时有成功燃放的最优呢?因为这样肯定做6次再全部放掉最优,所以第一轮要改为做6次)
每一轮的时间花费为(k*n+m),每轮有烟花成功燃放的概率为1-(1-p)^k.这是一个几何分布。
它的期望轮数为E=1/(1-(1-p)^k).
所以期望时间为(k*n+m)/(1-(1-p)^k).
三分找一下最小值。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define LL long long #define DB double LL n,m; DB p; DB slove(LL k) { // cout<<(DB)((1.*k*n)+m)<<endl; // cout<<(1.-pow(1-p,k))<<endl; return ((1.*k*n)+m)/(1.-pow(1-p,k)); } int main() { int T; scanf("%d",&T); while(T--) { cin>>n>>m; cin>>p; p=p*0.0001; LL l=1,r=1000000000; while(l<r) { // cout<<l<<" "<<r<<endl; LL midl=l+(r-l)/3; LL midr=r-(r-l)/3; // cout<<slove(midl)<<" "<<endl; if(slove(midl)>slove(midr)) l=midl+1; else r=midr-1; } printf("%.10lf ",slove(l)); } return 0; }