设策略为每次造 x 个烟花然后放一次,不断如此操作,直到达成为止,设 q=1-p10^{-4},则期望值为: E=\sum_{i=1}^\infty i(xn+m)(q^x)^{i-1}(1-q^x) 提取变量,即设 w=q^x,即求 S_i=\sum_{j=1}^i jw^{j-1} ,代入错位相减法公式解得 A=\dfrac1{w-1},B=-\dfrac1{(w-1)^2},即 S_i=(Ai+B)q^i-B 故 \lim_{i\to\infty }S_i=\dfrac{1}{(w-1)^2},即: E=\dfrac{(xn+m)(1-q^x)}{(q^x-1)^2}=\dfrac{xn+m}{1-q^x} 即求一个正整数 x,使一元函数 E(x) 最小并输出最值。
求导得: E'(x)=\dfrac{n(1-q^x)+(xn+m)(-q^x\ln q)}{(1-q^x)^2} 显然 n,m,q > 0,注意到 q < 1,有 \ln q <0。观察可知函数如果不单调,一定是 U 型的,不妨直接三分求解。
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using db = double;
ll t, n, m, p;
db q;
db f(ll x)
{
return (x * n + m) / (1 - pow(q, x));
}
signed main()
{
scanf("%lld", &t);
while (t--)
{
scanf("%lld%lld%lld", &n, &m, &p);
q = 1 - 1e-4 * p;
ll lf = 1, rf = 1e9;
db ans = 1e21;
while (lf < rf)
{
ll lc = (2 * lf + rf) / 3, rc = (2 * rf + lf + 2) / 3;
db lv = f(lc), rv = f(rc);
ans = min({ans, lv, rv});
if (lv < rv)
{
rf = rc - 1;
}
else
{
lf = lc + 1;
}
}
printf("%.12lf\n", ans);
}
return 0;
}