码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ2227 [Zjoi2011]看电影(movie)

时间:2018-03-06 10:18:48      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:cst   tin   amp   algo   pre   zoj   cstring   cpp   source   

Description

\(k\)个座位,\(n\)个人依次过来,每人随机从\(k\)个座位中选择一个,并从它开始不停向后走直到遇到空座位坐下。求所有人都能坐下的概率(即没有人走到第\(k+1\)个位置)。\(n, k\leq200\),答案以有理数形式输出。

Solution

我们在最后一个座位之后添加第\(k+1\)个座位,并把这些座位连成环(\(k+1\)后面是第\(1\)个)。并令所有人可以从\(k+1\)个座位中任选一个。

那么现在每个座位坐到人的概率都相同(因为环是对称的),为\(\frac n{k+1}\)。答案实际上就是第\(k+1\)的座位没有人的概率,即\(\frac{k-n+1}{k+1}\)。但是这样是在所有人都可以选\(k+1\)的情况下的。而如果有人选了\(k+1\)就一定没有算到这个概率里,所以只需要乘上\(\left(\frac{k+1}k\right)^n\)即可。

所以答案即为
\[ \frac{(k-n+1)(k+1)^{n-1}}{k^n} \]

有理数计算的话,质因数分解+高精即可。

Code

#include <algorithm>
#include <cstdio>
#include <cstring>
const int N = 205;
int p[N];
int A[10000], len;
void add(int n, int m) {
  for (int i = 2; i <= n; ++i) if (!(n % i)) {
    while (!(n % i)) {
      p[i] += m;
      n /= i;
    }
  }
}
void mul(int x) {
  for (int i = 0, t = 0; i < len || t; ++i) {
    t = (A[i] = A[i] * x + t) / 10;
    A[i] %= 10;
    if (i >= len) len = i + 1;
  }
}
int main() {
  int T;
  scanf("%d", &T);
  while (T--) {
    int n, k;
    scanf("%d%d", &n, &k);
    if (n > k) { puts("0 1"); continue; }
    memset(p, 0, sizeof p);
    add(k - n + 1, 1);
    add(k + 1, n - 1);
    add(k, -n);
    memset(A, 0, sizeof A);
    A[0] = len = 1;
    for (int i = 1; i <= k + 1; ++i)
      for (int j = 0; j < p[i]; ++j)
        mul(i);
    while (len--) printf("%d", A[len]);
    putchar(‘ ‘);
    memset(A, 0, sizeof A);
    A[0] = len = 1;
    for (int i = 1; i <= k + 1; ++i)
      for (int j = p[i]; j < 0; ++j)
        mul(i);
    while (len--) printf("%d", A[len]);
    putchar(\n);
  }
}

BZOJ2227 [Zjoi2011]看电影(movie)

标签:cst   tin   amp   algo   pre   zoj   cstring   cpp   source   

原文地址:https://www.cnblogs.com/y-clever/p/8512363.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!