数据结构_三分+概率

题意:

有一个人,做一个烟花需要n分钟,做的好的概率是p * 0.0001,点燃一次烟花需要m分钟(不管有多少个烟花),如果点燃的烟花中有一个好的,就停止做烟花,否则就继续练习,问最少需要多长的练习时间??

输入
第一行一个t,代表t组样例
接下来的t行,每一行输入n,m,p

输出
最小的练习时间

输入
3
1 1 5000
1 1 1
1 2 10000

输出
4.0000000000
10141.5852891136
3.0000000000

思路:

首先先来说明,每一次都是生产相同数量点燃。
原因:这是需要最优策略。假设k=9是最优策略,那么就要一直选择9进行燃烧。
所以对于每次进行的燃烧,都要等到生产了k(9)个时才能进行一块点燃。
假设每k个释放一次,那么成功的概率为1-(1-p)^k(p=p*1e-4)。
释放几次后可以得到完美的期望------几何分布:

几何分布:离散型概率分布。其中一种定义为:在n次伯努利试验中,
试验k次才得到第一次成功的概率。详细的说,是:前k-1次皆失败,
第k次成功的概率。
期望E(x)=1/p;(概率论公式,不再赘述)
所以可以得
f(k)=E(x)(kn+m) = (k*n+m)/[1-(1-p)^k]。

寻找最优解,最小值。猜测是开口向上的抛物线—验证,
测试1-10000的k看数据变化。 验证------三分答案:

代码实现:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 5;
double n,m,p;
double qpow(double a,int b){
	double res = 1.0;
	while(b){
		if(b & 1) res = res * a;
		b >>= 1;
		a = a * a;
	}
	return res;
}
double f(int k){
	double tmp = 1.0 - qpow(1 - p,k);
	if(tmp == 0) return (double)0x3f3f3f3f3f3f3f3f;
	else return (k * n + m) / tmp;
}
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		scanf("%lf%lf%lf",&n,&m,&p);
		p = p * 0.0001;
		int l = 1,r = 0x3f3f3f3f;
		double ans = (double)0x3f3f3f3f3f3f3f3f;
		while(r > l){
			int lm = l + (r - l) / 3;
			int rm = r - (r - l) / 3;
			ans = min(ans,min(f(lm),f(rm)));
			if(f(lm) < f(rm)){
				r = rm - 1;
			}
			else l = lm + 1;
		}
		printf("%.10lf\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值