さ、300 点!?
問題概要
個の中からランダムに選ぶ試行を 回行う。それぞれのものが出た回数が 回になる確率を としたとき、 を満たすような最小の を求めよ。
制約
考えたこと
確率を求めること自体は難しくなくて、
で求められる。が、この値はあまりにも小さくなりうるので対数をとる。具体的には log10 関数を用いる。そうすると
となる。あとは を頑張って前処理で計算しておけば OK。
#include <iostream> #include <vector> #include <cmath> using namespace std; const int MAX = 101010; const long double EPS = 1e-6; vector<long double> p; int main() { p.assign(MAX, 0); for (int i = 1; i < MAX; ++i) p[i] = p[i-1] + log10(i); int N, M; cin >> N >> M; long double prob = -p[N]; for (int i = 0; i < M; ++i) { int r; cin >> r; prob += p[r]; } prob += log10(M) * N; cout << ceil(prob) << endl; }