题目描述
“为世界上所有的美好而战!”
小Q同学最近沉迷“稳固3”,为了从最新的蛋池中抽出自己喜欢的角色卡,不惜氪下重金。
在这个游戏中,氪一单可以得到x个宝石,而抽一次卡需要花费y个宝石,由于游戏策划十分“良心”,抽卡是独立重复实验,单次抽出目标角色卡的概率是p且不存在所谓的“保底”。
为了尽可能省钱,小Q同学只会在抽卡所需宝石不足的情况下再氪一单,并且抽出目标角色卡之后会立即停止抽卡,他想知道为了抽出目标角色卡期望要氪多少单。
小Q同学最近沉迷“稳固3”,为了从最新的蛋池中抽出自己喜欢的角色卡,不惜氪下重金。
在这个游戏中,氪一单可以得到x个宝石,而抽一次卡需要花费y个宝石,由于游戏策划十分“良心”,抽卡是独立重复实验,单次抽出目标角色卡的概率是p且不存在所谓的“保底”。
为了尽可能省钱,小Q同学只会在抽卡所需宝石不足的情况下再氪一单,并且抽出目标角色卡之后会立即停止抽卡,他想知道为了抽出目标角色卡期望要氪多少单。
输入描述:
输入只有一行,包含三个整数x,y,q(0<x,y,q<10000),分别表示氪一单能得到的宝石数、抽一次卡需要的宝石数以及抽出目标角色卡的概率p乘以10000之后的数。
输出描述:
输出一行,包含一个浮点数,表示抽出目标角色卡期望氪的单数,要求绝对误差或相对误差不超过 1e-9。
示例1
输入
6480 280 98
输出
4.921219218795631382
题解
模拟。
每次模拟买、模拟抽就可以了,计算的时候有一些优化,多次抽的话只需要一次计算。
#include <bits/stdc++.h> using namespace std; long long x, y, q; double u[100000]; double f[100000]; int main() { scanf("%lld%lld%lld", &x, &y, &q); double p = 1.0 * q / 10000.0; u[0] = 1.0; f[0] = 1.0; for(int i = 1; i <= 20000; i ++) { f[i] = f[i - 1] * (1.0 - p); u[i] = u[i - 1] + f[i]; } double pp = 1.0; double ans = 0.0; long long hav = 0; long long tot = 0; for(int i = 1; i <= 1000000; i ++) { int need = y - hav; int now = need / x; if(need % x) now ++; tot = tot + now; hav = hav + now * x; int r = hav / y; ans = ans + 1.0 * pp * p * tot * u[r - 1]; hav = hav % y; pp = pp * f[r]; } printf("%.20f\n", ans); return 0; }