https://codeforc.es/contest/1194/problem/F

下面是错的。

看起来有点概率dp的感觉?

给你T秒钟时间,你要按顺序处理总共n个事件,每个事件处理花费的时间是ti秒钟,有一半的概率失手导致多花1秒钟。求T时间内处理完事情的总数的期望。

处理完第1个事件,有0.5概率花t1,有0.5概率花t1+1。

处理完第2个事件,有0.25概率花t1+t2,有0.5概率花t1+t2+1,有0.25概率花t1+t2+2。

处理完第3个事件,有0.125概率花t1+t2+t3,有0.375概率花t1+t2+t3+1,有0.375概率花t1+t2+t3+2,有0.125概率花t1+t2+t3+3。


一开始的思路不对,一开始是按“最后一个结束的元素”来分类,这样子导致非常难计算,应该独立算每个元素的贡献概率。


答案\(E=\sum\limits_{i=1}^{n}P(i)\),\(P(i)\)表示第\(i\)个元素贡献的概率。在前面的很多个里面这样的概率是1。

先累计就算每一次都失手还是能做完的前面的若干个。记第一个不一定能够做完的为x。


第一步,统计结束于\(x\)的,失手次数的上限\(d_x\)不能超过\(x\),也要满足\(pre_x+d_x<=T\),即不能超过\(T-pre_x\)。还要保证最后下一个元素\(x+1\)不能被选到吗?其实并不需要这么做,只要在选下一个的时候加上就可以了。

故\(d_x=min(x,T-pre_x)\)。

失手\([0,d_x]\)次会导致贡献第\(x\),这样的贡献是

\(P(x)=(\frac{1}{2})^{x}\sum\limits_{i=0}^{d_x}C_x^i\)


第二步,统计结束于\(x+1\)的,失手次数\(d_{x+1}\)不能超过\(x+1\),也要满足\(pre_{x+1}+d_{x+1}<=T\),即不能超过\(T-pre_{x+1}\)。

\(d_{x+1}=min(x+1,T-pre_{x+1})\)

失手\([0,d_{x+1}]\)次会导致贡献\(x+1\),这样的贡献是

\(P(x+1)=(\frac{1}{2})^{x+1}\sum\limits_{i=0}^{d_{x+1}}C_{x+1}^i\)


最后是一个奇怪的效率问题了。应该也是这道题第二值得学习的地方(第一值得学习的是统计的思路)。

第一个是要注意到组合数的一个变形:

\(C_n^k+C_{n}^{k+1}=C_{n+1}^{k+1}\),也就是按第\(n+1\)个元素有没有被选进这\(k+1\)个元素分类。

所以

\(\sum\limits_{i=0}^{k+1}C_{n+1}^i=C_{n}^{k+1}+C_{n}^{k}+C_{n}^{k}+C_{n}^{k-1}+...+C_{n}^{1}+C_{n}^{0}+C_{n}^{0}\)

也就是:

\(\sum\limits_{i=0}^{k+1}C_{n+1}^i=C_{n}^{k+1}+2*\sum\limits_{i=0}^{k}C_{n}^i\)

第二个是要注意到\(d_{x+1}<=d_{x}+1\),这不是很显然吗,多一件事情肯定要花多至少1秒去处理,就必须少失误一次?这个东西可以保证,上标是单调下降的。

所以可以O(n)转移出所有需要的组合数。因为上下标都是单调的。


还是有了两处溢出错误以及一个T==0也是合法情况的问题。

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. const int mod = 1e9 + 7;
  5. const int inv2 = (mod + 1) >> 1;
  6. int n, curn, curk;
  7. ll T, sigmaC, E, inv2x;
  8. const int MAXN = 2e5;
  9. ll inv[MAXN + 5], fac[MAXN + 5], invfac[MAXN + 5];
  10. void init_inv(int n = MAXN) {
  11. inv[1] = 1;
  12. for(int i = 2; i <= n; i++) {
  13. inv[i] = inv[mod % i] * (mod - mod / i) % mod;
  14. }
  15. }
  16. void init_fac_invfac(int n = MAXN) {
  17. init_inv(n);
  18. fac[0] = 1, invfac[0] = 1;
  19. for(int i = 1; i <= n; i++) {
  20. fac[i] = fac[i - 1] * i % mod;
  21. invfac[i] = invfac[i - 1] * inv[i] % mod;
  22. }
  23. }
  24. inline ll C(ll n, ll m) {
  25. if(n < m)
  26. return 0;
  27. return fac[n] * invfac[n - m] % mod * invfac[m] % mod;
  28. }
  29. int t[200005];
  30. ll pret[200005];
  31. void calc_sigmaC(int x) {
  32. ll tmp = 0;
  33. int dx = min((ll)x, T - pret[x]);
  34. for(int i = 0; i <= dx; i++) {
  35. tmp += C(x, i);
  36. if(tmp>=mod)
  37. tmp-=mod;
  38. }
  39. sigmaC = tmp;
  40. curn = x;
  41. curk = dx;
  42. }
  43. void next_sigmaC(int nextx) {
  44. int dx1 = min((ll)nextx, T - pret[nextx]);
  45. ll tmp = sigmaC;
  46. tmp = 2ll * tmp % mod;
  47. tmp = (tmp + C(curn, curk + 1)) % mod;
  48. curn++;
  49. curk++;
  50. while(curk > dx1) {
  51. tmp = (tmp + mod - C(curn, curk)) % mod;
  52. curk--;
  53. }
  54. sigmaC = tmp;
  55. }
  56. int main() {
  57. #ifdef Yinku
  58. freopen("Yinku.in", "r", stdin);
  59. //freopen("Yinku.out", "w", stdout);
  60. #endif // Yinku
  61. init_fac_invfac();
  62. while(~scanf("%d%lld", &n, &T)) {
  63. pret[0] = 0;
  64. for(int i = 1; i <= n; i++) {
  65. scanf("%d", &t[i]);
  66. pret[i] = pret[i - 1] + t[i];
  67. }
  68. E = 0;
  69. inv2x = inv2; //与x配对的sigmaC的系数
  70. int x = 1;
  71. while(x <= n && pret[x] + x <= T) {
  72. x++;
  73. E++;
  74. inv2x = (inv2x * inv2) % mod;
  75. }
  76. //x现在是第一个不一定可以的
  77. if(x <= n) {
  78. calc_sigmaC(x);
  79. for(; x <= n; x++) {
  80. E = (E + inv2x * sigmaC % mod) % mod;
  81. if(T - pret[x + 1] < 0)
  82. break;
  83. next_sigmaC(x + 1);
  84. inv2x = (inv2x * inv2) % mod;
  85. }
  86. }
  87. printf("%lld\n", E);
  88. }
  89. }

需要学习的是分类统计的思路,以及组合数直接转移的思想。

Codeforces - 1194F - Crossword Expert - 组合数学的更多相关文章

  1. Codeforces 1194F. Crossword Expert

    传送门 考虑每一个位置的期望贡献 $P[i]$ 对于第 $k$ 个位置,设 $sum=\sum_{i=1}^{k}t[k]$,那么 $T-sum$ 即为用最短时间完成完位置 $k$ 后多出来的空闲时间 ...

  2. Crossword Expert CodeForces - 1194F (期望)

    大意: $n$个题, 按照第$i$题随机$t_i$或$t_i+1$秒钟完成, 最多做$T$秒, 求做题数期望. 期望转为做题数$\ge x$的方案数之和最后再除以总方案数 这是因为$\sum\limi ...

  3. codeforces 1194F (组合数学)

    Codeforces 11194F (组合数学) 传送门:https://codeforces.com/contest/1194/problem/F 题意: 你有n个事件,你需要按照1~n的顺序完成这 ...

  4. CF1194F Crossword Expert(数论,组合数学)

    不难的一题.不知道为什么能 $2500$…… 不过场上推错了一直不会优化…… 首先考虑 $f_i$ 表示恰好做完前 $i$ 道题的概率. 这样很难算.修改一下,$f_i$ 表示做完至少 $i$ 道题的 ...

  5. Codeforces 1090B - LaTeX Expert - [字符串模拟][2018-2019 Russia Open High School Programming Contest Problem B]

    题目链接:https://codeforces.com/contest/1090/problem/B Examplesstandard input The most famous characters ...

  6. Codeforces 995F Cowmpany Cowmpensation - 组合数学

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一个棵$n$个点的有根树和整数$D$,给这$n$个点标号,要求每个节点的标号是正整数,且不超过父节点的标号,根节点的标号不得超过D. 很容 ...

  7. Codeforces 40E Number Table - 组合数学

    题目传送门 传送门I 传送门II 题目大意 给定一个$n\times m$的网格,每个格子上要么填$1$,要么填$-1$,有$k$个位置上的数是已经填好的,其他位置都是空的.问有多少种填法使得任意一行 ...

  8. Codeforces 37D Lesson Timetable - 组合数学 - 动态规划

    题目传送门 神奇的门I 神奇的门II 题目大意 有$n$组学生要上课2次课,有$m$个教室,编号为$1$到$m$.要确定有多少种不同的安排上课的教室的方案(每组学生都是本质不同的),使得它们满足: 每 ...

  9. Codeforces 711D Directed Roads - 组合数学

    ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it co ...

随机推荐

  1. linux为 rsync 添加开机启动

    [root@rsync-server-1 /]# echo "/usr/bin/rsync --daemon" >> /etc/rc.local [root@rsync ...

  2. FMC228- 四路16位1.2Gsps DA FMC子卡模块

    FMC228- 四路16位1.2Gsps DA FMC子卡模块 一.概述          FMC连接器是一种高速多pin的互连器件,广泛应用于板卡对接的设备中,特别是在xilinx公司的所有开发板中 ...

  3. Linux性能优化从入门到实战:07 CPU篇:CPU性能优化方法

    性能优化方法论   动手优化性能之前,需要明确以下三个问题:   (1)如何评估性能优化的效果? 确定性能的量化指标.测试优化前的性能指标.测试优化后的性能指标.   量化指标的选择.至少要从应用程序 ...

  4. 构建LNMP+memcached服务

    通过PHP页面实现对memcached服务器的数据操作,实现以下目标: - 为PHP安装memcache扩展 - 创建PHP页面,并编写PHP代码,实现对memcached的数据操作 环境:部署LNM ...

  5. MYSQL学习笔记——数据类型

    mysql的数据类型可以分为三大类,分别是数值数据类型.字符串数据类型以及日期时间数据类型. 数值数据类型                                               ...

  6. ps:选区的存储及载入

    有时候需要把已经创建好的选区存储起来,方便以后再次使用.就要使用选区存储功能. 创建选区后,直接点击右键(限于选取工具)出现的菜单中就“存储选区”项目.也可以使用菜单[选择 存储选区].会出现一个名称 ...

  7. HTML表单(来自MDN的总结)

    表单介绍 HTML表单是用户和web站点或应用程序之间交互的主要内容之一.它们允许用户将数据发送到web站点.大多数情况下,数据被发送到web服务器,但是web页面也可以拦截它自己并使用它. HTML ...

  8. java.util.Date 与 java.sql.Date 相关知识点解析

    问:java.sql.Date 和 java.util.Date 有什么区别?   答:这两个类的区别是 java.sql.Date是针对 SQL 语句使用的,它只包含日期而没有时间部分,一般在读写数 ...

  9. cmd优化

    cmd很方便,很简约,但是看久了也会视觉疲劳 因此我们来优化一下cmd 原博文是我的一位同学写的,链接如下:https://www.cnblogs.com/ljsh/p/10877715.html 打 ...

  10. php长连接和短连接的使用场景

    短连接 连接->传输数据->关闭连接 比如HTTP是无状态的的短链接,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接. 具体就是 浏览器client发起并建立T ...