也许更好的阅读体验

\(\mathcal{Description}\)

原题链接

题目大意

该题目有两个问题

  • \(Task\ 1\),有\(n\)个人\(n\)个座位,每个人都有一个对应的座位,每个人排队进入去坐座位,小\(A\)是第一个,然而小\(A\)忘记了自己的位置,于是他进去后自己随便坐了一个位置,之后的人进来后若发现自己的位置已经被人坐了,那么他就随便坐一个没人坐的位置,如果自己的位置没有被人坐,那么就会坐自己的位置,问最后一个进来的人坐到自己的位置概率是多少

  • \(Task\ 2\),有\(m\)个人\(m\)个座位,该问题与上面问题差不多,但是每个人并不会排队进去,而是随机的进入,即进入的顺序随机的(包括小\(A\)的进入时间),仍然问最后一个进来的人坐到自己的位置的概率是多少

复杂度要求在\(O(n^3)\)以内

实际上只要\(O(1)\)

\(\mathcal{Solution}\)

这题有点考思维,博主想了很久(博主太蒻了),所以会写一些心得,在引用里面,只想知道题解可以跳过

主要是考逆向思维,以及一个问题的转化

不要怕概率这个玩意,尽量想办法避开它,或者只用最简单的概率计算

考虑递推

想了很久如何正着推,但是不知道某个人进来时是否可以坐座位,设了很多方程,都是找不到转移或者错误的转移

一般递推都会是可以将某一个状态变成另一个状态

所以我们要找到什么样的状态是有联系的

  • \(Task\ 1\)

    一直想找到一种方法可以考虑到一个座位是否被坐,博主突然发现了一个性质

    我们知道,当小\(A\)坐在了第\(x\)个进来的人的位置,那么第\(2\)到\(x-1\)个人进来时都是直接坐在自己座位上

    这条性质十分显然也十分简单,可是却很容易将其忽视

    博主忽视了1个多小时...

    另外,小\(A\)坐在任何一个位置的概率都是\(\frac{1}{n}\)

    于是我们可以利用这样的两个性质,开始递推

    我们不认为小\(A\)是忘记了自己的座位,而是不知道自己的座位

    设\(f[i]\)表示有\(i\)个人时,第一个人不知道自己座位(即第一个人会乱坐)的答案

    当小\(A\)坐在了自己的座位上时,之后最后一个人坐在自己座位的概率为\(100\%\)

    当小\(A\)坐了第\(j\)个人的座位时,当第\(j\)个人来找座位时,我们可以认为原本小\(A\)的座位是他的座位,而他不知道

    因为当他坐在小\(A\)的座位上时,对后面上来的人都没有影响了

    这样,若小\(A\)坐了\(j\)号座位,当\(j\)来找座位时,相当于是考虑原来的问题,只不过\(n\)变成了\(n-j+1\)

    于是我们得到了这样的递推式

    \(\begin{aligned}f[i]=\frac{1}{i}\sum_{j=1}^{i-1}f[j]\end{aligned}\)

    初值\(f[1]=1\)

    上面这个式子可以记一下前缀和然后就可以\(O(1)\)转移了

    然后博主发现从\(2\)开始,答案都是\(\frac{1}{2}\)

  • \(Task\ 2\)

    由于是完全随机的顺序,所以没有了上面那个性质

    在想出来\(Task\ 1\)的做法后,博主坚信一定是递推,但是又想了一会没想出来

    在内心坚定自己时欧皇的情况下,博主毅然蒙了两个结论提交了程序,于是博主就多了两个罚时...

    因为已经想出来第一问,博主舍不得,于是博主就继续肝了一会儿,又有了一个想法

    仍然是考虑递推,受到\(Task\ 1\)的启发,所以仍然按照这个思维模式

    因为是随机顺序,所以小\(A\)是第几个来坐座位的概率都是\(\frac{1}{m}\)

    设\(f[i]\)表示有\(i\)个人的答案

    因为不知道座位是一种特殊的状态,所以我们仍然对它下手

    考虑小\(A\)是第\(j\)个来坐座位的人

    这样前\(j-1\)个人都是坐在自己座位上

    于是现在要考虑的就是有\(i-j+1\)个人,小\(A\)第一个来坐座位,剩下的人是随机来坐座位的情况

    设\(g[i]\)表示有\(i\)个人,小\(A\)第一个来坐座位,剩下的人是随机来坐座位,最后一个人坐到自己座位上的答案

    然后我们枚举小\(A\)是第几个

    得到这样的递推式

    \(\begin{aligned}f[i]=\frac{1}{i}\sum_{j=1}^{i}g[i]\end{aligned}\)

    于是现在就是要想办法求\(g\)了,终于把问题转化为一个感jio简单些的问题了

    考虑求\(g[i]\),我们仍然按照上面的思维模式,考虑小\(A\)坐在了第\(j\)个来选座位的人的座位

    因为是随机顺序,所以小\(A\)随便坐一个位置,其是第\(j\)(\(j\)任取)个上来的人的座位的概率仍然是\(\frac{1}{i}\)

    于是,在\(j\)前面的人都坐自己的位置,从\(j\)开始,又是一个\(i-j+1\)个人的问题,当然,别忘了坐在自己坐

    所以得到\(g\)的递推式

    \(\begin{aligned}g[i]=\frac{1}{i}\sum_{j=1}^{i-1}g[i]\end{aligned}\)

    诶,这个和\(Task\ 1\)的\(f\)是一样的.....

    于是问题就得到了解决

    真是可喜可贺可喜可贺...

噢,这还只是\(O(n)\)是吧

然后我们经过打表发现

对于\(Task\ 1\)

有\(f[1]=1,f[n]=0.5(n>1)\)

然后对于\(Task\ 2\)

有\(g[m]=\frac{m+1}{2m}\)

\(\mathcal{Code}\)

这里仍然给了\(f,g\)的递推(以免有不太明白的地方),但是直接用上面的结论\(O(1)\)输出的

/*******************************
Author:Morning_Glory
LANG:C++
Created Time:2019年08月31日 星期六 15时45分43秒
*******************************/
#include <cstdio>
#include <fstream>
using namespace std;
const int maxn = 55;
const int mx = 50;
int T,n,m;
double sum;
double f[maxn],g[maxn];
void init ()
{
sum=g[1]=f[1]=1,f[2]=1.0/2.0;
for (int i=2;i<=mx;++i) f[i]=1.0/i*sum,sum+=f[i],g[i]=sum/(double)i;
}
int main()
{
scanf("%d",&T);
init();
for (int t=1;t<=T;++t){
scanf("%d%d",&n,&m);
printf("Case #%d: %.6lf %.6lf\n",t,n>1?0.5:1,(double)(m+1)/(double)(2.0*m));
}
return 0;
}

如有哪里讲得不是很明白或是有错误,欢迎指正

如您喜欢的话不妨点个赞收藏一下吧

[The 2019 Asia Yinchuan First Round Online Programming] D Take Your Seat的更多相关文章

  1. The 2019 Asia Yinchuan First Round Online Programming F. Moving On

    t题目链接:https://nanti.jisuanke.com/t/41290 思路:题目意思很容易想到floyd,但是由于危险度的限制,我们该怎么跑floyd呢. 一开始理解错题目了,以为u-&g ...

  2. “2018宁夏邀请赛 ” 兼 “The 2019 Asia Yinchuan First Round Online Programming”

    ------------7题弟弟,被各位半小时13题的大佬打惨了(滑稽)---------- 签到题就不写了. F :Moving On            (1247ms) 题意:给定大小为N的带 ...

  3. The 2019 Asia Nanchang First Round Online Programming Contest

    传送门 A. Enju With math problem 题意: 给出\(a_1,\cdots,a_{100}\),满足\(a_i\leq 1.5*10^8\). 现在问是否存在一个\(pos\), ...

  4. The 2019 Asia Nanchang First Round Online Programming Contest C(cf原题,线段树维护矩阵)

    题:https://nanti.jisuanke.com/t/41350 分析:先将字符串转置过来 状态转移,因为只有5个状态,所以 i 状态到 j 状态的最小代价就枚举[i][k]->[k][ ...

  5. The 2019 Asia Nanchang First Round Online Programming Contest E. Magic Master

    题目链接:https://nanti.jisuanke.com/t/41352 题目意思还是好理解的,看过的人不多,感觉是被通过量吓到了.其实就是个水题,反向模拟就好了, 用队列模拟,反向模拟,它要放 ...

  6. The 2019 Asia Nanchang First Round Online Programming Contest B. Fire-Fighting Hero

    题目链接:https://nanti.jisuanke.com/t/41349 题意:有一个灭火英雄,和一个灭火团队,一个人与一个团队比较. 灭火英雄到其他灭火点的最短路最大值,与一个团队到其他灭火点 ...

  7. The 2019 Asia Nanchang First Round Online Programming Contest The Nth Item

    The Nth Item 思路: 先用特征根法求出通向公式,然后通向公式中出现了\(\sqrt{17}\),这个可以用二次剩余求出来,然后可以O(\(log(n)\))求出. 但是还不够,我们先对\( ...

  8. H. The Nth Item(The 2019 Asia Nanchang First Round Online Programming Contest)

    题意:https://nanti.jisuanke.com/t/41355 给出N1,计算公式:A=F(N)Ni=Ni-1 ^ (A*A),F为类斐波那契需要矩阵快速幂的递推式. 求第k个N. 思路: ...

  9. E.Magic Master(The 2019 Asia Nanchang First Round Online Programming Contest)

    直接模拟orhttps://blog.csdn.net/liufengwei1/article/details/100643831

随机推荐

  1. useEffect 实现 componentWillUnmount生命周期函数(四)

    在写React应用的时候,在组件中经常用到componentWillUnmount生命周期函数(组件将要被卸载时执行).比如我们的定时器要清空,避免发生内存泄漏;比如登录状态要取消掉,避免下次进入信息 ...

  2. 用variant的数据来推导基因表达 | Imputation of Expression Using PrediXcan

    一个工具的逻辑得足够完善.意义足够重大,才有资格发在NG上. A gene-based association method for mapping traits using reference tr ...

  3. Oracle数据库安装以及使用脚本创建数据库授权

    安装数据库 事实上Oracle安装 1.安装准备 Oracle的安装包下载以后是两个压缩包,同时选中两个压缩包右击进行解压 2.解压完成如下图所示 3.双击 setup.exe 文件进行安装,会弹出以 ...

  4. 宝塔 ssl https无法访问使用

    https 使用的是443端口 请确保  云上的与宝塔上的443端口开放即可

  5. 000 装docker

    直接参考别人的文章,经过验证,没有问题,需要网络. URL: https://www.cnblogs.com/qgc1995/archive/2018/08/29/9553572.html 我是虚拟机 ...

  6. [转]IE、FireFox、Chrome浏览器中关于URL传参中文乱码,解决兼容性问题!

    原文地址:https://cloud.tencent.com/developer/article/1334736 前台用url传值中文,后台用request.getParameter接收参数.在Fir ...

  7. flutter 主页面底部导航栏实现以及主题风格设置

    import 'package:flutter/material.dart'; import 'package:flutter_app/bottom_navigation_widget.dart'; ...

  8. Linux 在 TOP 命令中切换内存的显示单位

    顶部的内存信息可以在top运行时按E切换,每次切换转换率为1000,只是没有单位,切换的单位为 k,m,g,t,p: 1. 2. 3., 4. 底下的进程信息按e切换,每次切换转换率为1000,切换的 ...

  9. memcpy字节序问题

    /* memcpy用法详解 */ #include <stdio.h> #include <stdlib.h> #include <string.h> //memc ...

  10. oracle根据sqlID查找相对应的sql语句

    转: 根据sqlID查找相对应的sql语句 2019-07-25 14:47:20 猛豪 阅读数 567更多 分类专栏: 数据库   版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议 ...