ICPC2020南京 F Fireworks(概率論+三分)

傳送門

題目大意:做一個煙花花費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\n",slove(l));
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章