2020ICPC南京站 F-Fireworks(概率+三分)

 

 输入:

3
1 1 5000
1 1 1
1 2 10000

输出:

4.0000000000
10141.5852891136
3.0000000000

题目大意:有一个人正在制作烟花,这个人制作出一个烟花为“完美烟花”的概率为p/10000,这个人每次制作完烟花后可以有两种选择,一种选择是继续制作烟花,一种选择是花费m分钟,将当前制作出来的还没有燃放的烟花全部点燃,以此来验证这批烟花中是否含有“完美烟花”,他每次制作一个烟花的用时为n分钟,当他发现自己制作出一个"完美烟花"后,他就会去休息,问当他采取最优策略的时候,他至少需要花费多长事件才会去休息。

解题思路:

三分每次制作出k个烟花后选择一次性将其燃放,寻找最优策略,这时有人可能就会问,为什么最优策略是每次选择一样的k个烟花,每次选择的烟花就不会不一样多吗?其实对于这个问题,我们每次选择一次性燃放多少个烟花是相互独立的,那么如果我们上一次选择一次燃放k个烟花是最优策略,那么当前这次同样选择一次燃放k个烟花也一定是最优策略,两个问题的性质是相同的。

现在是给定一个数字x,如何计算一次选择x个烟花燃放的期望事件,公式如下:

\frac{1}{1-(1-p)^{x}}*(n*x+m)

前一项表示,我们把制作x个烟花当作一次操作,出现一个“完美烟花”所需要的操作次数

后一项表示一次操作所需要的代价,即x次制作时间n*x加一次点燃时间m

上代码:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
int t;
long long n,m;
double p;
long double f(long long x)
{
	return (n*x+m)/(1-pow(1-p,x));
}
double eps=1e-4;
int main()
{
	cin>>t;
	while(t--)
	{
	 cin>>n>>m>>p;
	 p=p/10000.0;
	 long long r=100000000,l=1;
	 long double ans=1e18;
	 while(r>l)
        {
            long long mid1=l+(r-l)/3,mid2=l+(r-l)*2/3;
            long double f1=f(mid1),f2=f(mid2);
            ans=min(ans,min(f1,f2));
            if (f1<f2) 
			r=mid2; 
			else 
			l=mid1+1;
        }
    	printf("%.8Lf\n",ans);

	}
	return 0;	
}
/*
1
1 1 1
*/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值