三分查找(2020icp南京F)

2020icpc南京F.Firework

题意:

制作一个烟花需要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;
}
原文地址:https://www.cnblogs.com/Tiork/p/14190102.html