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也是合法情况的问题。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll; const int mod = 1e9 + 7;
const int inv2 = (mod + 1) >> 1; int n, curn, curk;
ll T, sigmaC, E, inv2x; const int MAXN = 2e5; ll inv[MAXN + 5], fac[MAXN + 5], invfac[MAXN + 5]; void init_inv(int n = MAXN) {
inv[1] = 1;
for(int i = 2; i <= n; i++) {
inv[i] = inv[mod % i] * (mod - mod / i) % mod;
}
} void init_fac_invfac(int n = MAXN) {
init_inv(n);
fac[0] = 1, invfac[0] = 1;
for(int i = 1; i <= n; i++) {
fac[i] = fac[i - 1] * i % mod;
invfac[i] = invfac[i - 1] * inv[i] % mod;
}
} inline ll C(ll n, ll m) {
if(n < m)
return 0;
return fac[n] * invfac[n - m] % mod * invfac[m] % mod;
} int t[200005];
ll pret[200005]; void calc_sigmaC(int x) {
ll tmp = 0;
int dx = min((ll)x, T - pret[x]);
for(int i = 0; i <= dx; i++) {
tmp += C(x, i);
if(tmp>=mod)
tmp-=mod;
}
sigmaC = tmp;
curn = x;
curk = dx;
} void next_sigmaC(int nextx) {
int dx1 = min((ll)nextx, T - pret[nextx]);
ll tmp = sigmaC;
tmp = 2ll * tmp % mod;
tmp = (tmp + C(curn, curk + 1)) % mod;
curn++;
curk++;
while(curk > dx1) {
tmp = (tmp + mod - C(curn, curk)) % mod;
curk--;
}
sigmaC = tmp;
} int main() {
#ifdef Yinku
freopen("Yinku.in", "r", stdin);
//freopen("Yinku.out", "w", stdout);
#endif // Yinku
init_fac_invfac();
while(~scanf("%d%lld", &n, &T)) {
pret[0] = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &t[i]);
pret[i] = pret[i - 1] + t[i];
}
E = 0;
inv2x = inv2; //与x配对的sigmaC的系数
int x = 1;
while(x <= n && pret[x] + x <= T) {
x++;
E++;
inv2x = (inv2x * inv2) % mod;
}
//x现在是第一个不一定可以的
if(x <= n) {
calc_sigmaC(x);
for(; x <= n; x++) {
E = (E + inv2x * sigmaC % mod) % mod;
if(T - pret[x + 1] < 0)
break;
next_sigmaC(x + 1); inv2x = (inv2x * inv2) % mod;
}
}
printf("%lld\n", E);
}
}

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

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. .net core api迁移 3.0后Post 405 Method Not Allowed

    问题由来:.net core api之前是用 .net core 2.0开发的,测试过都是正常的,近期升级到了3.0,发现api get正常,post提示400,405 Method Not Allo ...

  2. 利用C51单片机模拟SPI进行双机通信

    SPI协议简述 SPI,是英语Serial Peripheral interface的缩写,顾名思义就是串行外围设备接口.由Motorola首创.SPI接口主要应用在 EEPROM,FLASH,实时时 ...

  3. 【转】C/C++产生随机数

    转自:https://www.cnblogs.com/vectors07/p/8185215.html C/C++怎样产生随机数:这里要用到的是rand()函数, srand()函数,C语言/C++里 ...

  4. hdu 4082 Hou Yi's secret(暴力枚举)

    Hou Yi's secret Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  5. Google Capture The Flag 2018 (Quals) - Reverse - Beginner's Quest - Gatekeeper

    参考链接:https://ctftime.org/task/6264 题目 It's a media PC! All fully purchased through the online subscr ...

  6. Photoshop画笔工具的使用

    现在我们按下[B]从工具栏选择画笔工具,如果选中了铅笔就[SHIFT B]切换到画笔.然后按下[D],它的作用是将颜色设置为默认的前景黑色.背景白色.也可以点击工具栏颜色区的默认按钮(下左图红色箭头处 ...

  7. 转义字符\e

    Windows 平台下,conio.h 中有许多操作控制台颜色.格式的函数.但是再 Linux 平台下却没有类似的函数.经过在网上的一番搜索,找到了解决此问题的方法——转义字符\e.注意,\e这种写法 ...

  8. 英语单词independent

    来源——https://www.docker.com/products/docker-hub 回到顶部 Share and Collaborate with Docker Hub Docker Hub ...

  9. 最佳实践 | 数据库迁云解决方案选型 & 流程全解析

    Oracle是非常强大的综合数据库,但同时也存在一些劣势,比如由于采用集中式架构,无法很好地实现横向扩展,并且其稳定性依赖于硬件.出于架构升级.降低成本和云化等需求,越来越多的企业需要“去Oracle ...

  10. zabbix创建钉钉报警

    https://juejin.im/post/5c8708eef265da2dd168a1c1 简介 家里搭建了zabbix去监控主机,邮件报警什么的都太麻烦了,所以直接使用钉钉机器人来提醒,下面是我 ...