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

题目链接:F-Fireworks_第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京)

题目描述

Kotori is practicing making fireworks for the upcoming hanabi taikai 1. It takes her n minutes to make a single firework, and as she is not really proficient in making fireworks, each firework only has a probability of to be perfect.

After she finishes making a firework, she can just start making the next firework, or take m minutes to light all the remaining fireworks finished before. If there is at least one perfect firework among the lit ones, she will be happy and go to rest. Otherwise, she will continue practicing. Can you tell her the minimum expected practicing time before she goes to rest if she takes the optimal strategy?

Notice that no matter how many fireworks remain, it always takes m minutes to light them all.

1Hanabi taikai: Romaji of the Japanese word "花火大會", which means the firework... err... party?

输入描述:

There are multiple test cases. The first line of the input contains an integer T () indicating the number of test cases. For each test case:

The first and only line contains three integers n, m and p (, ).

输出描述:

For each test case, output one line containing one number indicating the minimum expected practicing time.

Your answer will be considered correct if and only if the absolute or relative error does not exceed .
示例1

输入

3 1 1 5000 1 1 1 1 2 10000
3
1 1 5000
1 1 1
1 2 10000

输出

4.0000000000 10141.5852891136 3.0000000000
4.0000000000
10141.5852891136
3.0000000000

题目大意

你每做一个烟花要n分钟,释放已做好的所有烟花需要m分钟,每只烟花成功释放的概率为p。问你在采取最优策略的前提下,直到成功释放第一个烟花时最小的期望时间花费。

分析

开始的时候理解错了意思,算了半天的平均期望。后来意识到我的做法不符合“最优策略”的要求。

再思考因为每次都是集中释放所有做好的,所以可以假设当取最优策略时,设每制作k个烟花后集中释放一次。这个问题可以转化为每次制作并释放k个烟花,重复这一过程直到某次释放时成功出现一个烟花为止,求当前期望时间花费。这就变成了一个典型的几何分布问题。

此时每轮的时间开销为 k ∗ n + m k*n+m kn+m,概率为至少成功释放一个烟花的概率 ( 1 − ( 1 − p ) k ) (1-(1-p)^k) (1(1p)k),根据几何分布公式得期望为 1 ( 1 − ( 1 − p ) k ) \frac {1}{(1-(1-p)^k)} (1(1p)k)1。乘以每轮开销得期望时间花费 k ∗ n + m 1 − ( 1 − p ) k \frac {k*n+m}{1-(1-p)^k} 1(1p)kkn+m

对上式打表或者求二阶导可知这是个单峰的凹函数。直接三分答案即可。

#include <bits/stdc++.h>
using namespace std;

long double fun(int k,int n,int m,long double p){
	return ((long double)k*n+m)/((long double)1.0-pow(1.0-p,k));
}

int main(){
	int T;
	cin>>T;
	while(T--){
		int n,m;
		long double p;
		cin>>n>>m>>p;
		p*=(1e-4);
		int l=1,r=0x3f3f3f3f;
		while(l<r){
			int mid1=l+(r-l)/3,mid2=r-(r-l)/3;
			if(fun(mid1,n,m,p)<fun(mid2,n,m,p)) r=mid2-1;
			else l=mid1+1;
		}
		printf("%.10Lf\n",fun(l,n,m,p));
	}
	return 0;
}

参考资料

几何分布_百度百科
二分答案法、三分法_Hello ACM-CSDN博客
2020年ICPC南京区域赛题解 - 知乎

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值