题意:
制作一个烟花需要n分钟,把当前所有烟花全部点燃需要m分钟,每一个烟花有p*1e-4的概率是个好烟花,求在最优的操作策略下,点燃到一个好烟花的时间期望是多少?(n,m<1e9,p<=10000)
输入:T组数据,每组数据为n,m,p
解答:
显然,当选取每制作x个hanabi点燃一次的时间期望为 (n*x+m)/(1-pow(1-p/10000),x)
可以发现这是一个先递减后递增的函数,那单峰函数用三分算法可求解。
三分法:
以前不知道这个,做了这题才知道。
while(l<r)
{
ll mid1=l+(r-l)/3,mid2=r-(r-l)/3;
if(cal(mid1)<cal(mid2)) r=mid2-1;
else l=mid1+1;
}
AC代码
//三分算法
#include<bits/stdc++.h>
using namespace std;
#define f(i,a,b) for(int i=a;i<=b;++i)
#define ll long long
#define N 500005
inline ll read(){ll x;scanf("%lld",&x);return x;}
ll n,m,p;
long double cal(ll x)
{
return (long double)(n*x+m)/(1-pow(1-(long double)p/10000.0,x));
}
void solve()
{
n=read(),m=read(),p=read();
ll l=1,r=1e9;
while(l<r)
{
ll mid1=l+(r-l)/3,mid2=r-(r-l)/3;
if(cal(mid1)<cal(mid2)) r=mid2-1;
else l=mid1+1;
}
printf("%.10Lf\n",cal(l));
}
int main()
{
ll T=read();
while(T--) solve();
return 0;
}