• BZOJ2227 [Zjoi2011]看电影(movie)


    Description

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

    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 ight)^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('
    ');
      }
    }
    
  • 相关阅读:
    微信小程序常用的方法(留着用)
    微信小程序H5预览页面框架(二维码不隐藏)
    微信小程序H5预览页面框架
    关于微信小程序的一点经验
    微信小程序修改单选按钮的默认样式
    Tomcat8升级后URL中特殊字符报错出现原因
    线程的生命周期和状态控制
    多线程相关概率解释
    多线程面试题集锦三
    spring的xml文件的作用与实现原理
  • 原文地址:https://www.cnblogs.com/y-clever/p/8512363.html
Copyright © 2020-2023  润新知