- 题目Fireworks
- 题意:每做一个烟花需要消耗n分钟,每一次燃放之前做好的烟花需要m分钟,每一个烟花燃放成功的概率为p,问在最优策略下,直到成功燃放第一个烟花时最小的期望时间花费.
- 解析:因为每一次燃放之前做好的烟花后,将回到最初状态,所以肯定存在一个k值为每次制作k个烟花后燃放一次,这时可达到花费的时间期望最小; 设事件P为为每次制作k个烟花后燃放一次的过程中至少有一个烟花能够燃放成功,该事件P的概率为(1 - (1 - p)^k),假设该事件将发生1、2、3...n次,那么直到某一次有一个烟花燃放成功则停止,该事件的的概率分布相当于几何概型,所以期望为1 / (1 - (1 - p)^k),但每一次所花费的时间为k*n + m所以最后的期望为:(k * n + m)/ (1 / (1 - (1 - p)^k)),那么可猜测该函数为一个凹函数,利用三分找到该函数的极小值即可.
- 代码:
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long ll;
int t;
double n, m, p;
double qpow(double a, ll k)
{
double res = 1;
while(k)
{
if(k & 1) res *= a;
a *= a;
k >>= 1;
}
return res;
}
double calc(ll k)
{
return ((double)k * n + m) / (1 - qpow(1 - p, k));
}
int main()
{
cin >> t;
while(t --)
{
cin >> n >> m >> p;
p /= 10000;
ll l = 1, r = 1e9;
while(l < r)
{
ll mid1 = l + (r - l) / 3;
ll mid2 = r - (r - l) / 3;
if(calc(mid1) < calc(mid2)) r = mid2 - 1;
else l = mid1 + 1;
}
printf("%.10lf\n", calc(l));
}
return 0;
}