• 【BZOJ2227】[ZJOI2011] 看电影(组合数学)


    点此看题面

    • (n)个人和(k)个位置,轮到每个人时会随机给出一个数字(lin [1,k]),找到大于等于(l)的最小空位置坐下,如果没有则只能站着。
    • 求每个人都坐下的概率。
    • (n,kle200)

    概率=合法方案数/总方案数

    考虑这道题中总方案数是非常显然的,就是(k^n)

    因此,问题的核心就在于,如何求出合法方案数,对于这个就需要几步很妙的转化。

    我们不妨在最后添上一个位置(k+1),则第一个站着的人就可以坐到第(k+1)个位置上,因此没有人站着等价于第(k+1)个位置是空的。

    然后我们还可以在第(k+1)个位置之后加上一个传送门,把这个东西连成一个圆,保证每个人都能找到位置坐,方便答案的计算。(当然一个合法方案中传送门是不会被用到的,因为要用传送门就说明第(k+1)个座位非空,因此这步转化不会影响合法方案数)

    那么相当于每个人都可以在这(k+1)个位置中任选,根据之后每个人选的数与第一个的人选的数之差,一共有((k+1)^{n-1})种可能的选法。

    而这些不同的选法有一个共通之处,就是空位置数量都是(k-n+1)

    现在我们需要找一个位置作为第(k+1)个位置把环断开,只要满足选择的是这(k-n+1)个空位置中的某一个即可。

    因此合法方案数就应该是((k+1)^{n-1}(k-n+1))

    由于题目要求直接给出答案的既约分数,直接上Python就好了。

    代码:(O(Tn))

    def gcd(a,b):#最大公约数,用于约分
        return a if b==0 else gcd(b,a%b)
    Tt=int(input())
    for T in range(Tt):
        st=input().split()
        n=int(st[0])
        k=int(st[1])
        if(n>k):
            print("0 1")#如果n>k,显然无解
        else:
            a=((k+1)**(n-1))*(k-n+1)#合法方案数
            b=k**n#总方案数
            d=gcd(a,b)
            print(a//d,end=' ')
            print(b//d)
    
    
    败得义无反顾,弱得一无是处
  • 相关阅读:
    MATLAB数据处理快速学习教程
    dev -c++ 快捷键
    SQL 通配符
    如何利用SQL语句求日期的时间差值,并汇总网上的一些信息
    matlab使用常犯的错误
    matlab中将矩阵按照行打乱顺序的一个例子
    我所认识的PCA算法的princomp函数与经历 (基于matlab)
    java 读取本地的json文件
    Oracle数据库——SQL基本查询
    Oracle数据库——表的创建与管理
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ2227.html
Copyright © 2020-2023  润新知