problem

luogu

现有N(1≤N≤300)N(1 ≤ N ≤ 300)N(1≤N≤300) 个盘子,编号为1,2,3,…,N1,2,3,…,N1,2,3,…,N。

第 iii个盘中放有 ai(1≤ai≤3)a_i(1≤a_i ≤3)ai​(1≤ai​≤3)个寿司。

接下来每次执行以下操作,直至吃完所有的寿司。

从第 1,2,3,…,N1,2,3,…,N1,2,3,…,N 个盘子中任选一个盘子,吃掉其中的一个寿司。若没有寿司则不吃。

若将所有寿司吃完,请问此时操作次数的数学期望是多少?

solution

最直接地设 f(a1,a2,a3,...,an):f(a_1,a_2,a_3,...,a_n):f(a1​,a2​,a3​,...,an​): 第 iii 盘还剩 aia_iai​ 个寿司的期望次数。

那么枚举随机到的盘子,有方程:f(a1,a2,...,an)=1+∑i=1n1nf(a1,a2,...,max⁡(ai−1,0),...,an)f(a_1,a_2,...,a_n)=1+\sum_{i=1}^n\frac{1}{n}f(a_1,a_2,...,\max(a_i-1,0),...,a_n)f(a1​,a2​,...,an​)=1+∑i=1n​n1​f(a1​,a2​,...,max(ai​−1,0),...,an​)。

显然这个等式不能构成转移方程,因为存在原地打转(第 iii 盘寿司为空时,就变成了自身转移到自身,状态不变)的情况。

由于随机均匀分布,盘子的位置是不重要的,事实上我们真正关注的只有盘子中剩余寿司的数量。

而 aia_iai​ 寿司数量又只有四种取值 0/1/2/30/1/2/30/1/2/3。

不妨重新设 f(o,i,j,k):f(o,i,j,k):f(o,i,j,k): 当前还剩下 o/i/j/ko/i/j/ko/i/j/k 个盘子中有 0/1/2/30/1/2/30/1/2/3 个寿司。

则有转移:
f(o,i,j,k)=1+onf(o,i,j,k)+inf(o+1,i−1,j,k)+jnf(o,i+1,j−1,k)+knf(o,i,j+1,k−1)f(o,i,j,k)=1+\frac{o}{n}f(o,i,j,k)+\frac{i}{n}f(o+1,i-1,j,k)+\frac{j}{n}f(o,i+1,j-1,k)+\frac{k}{n}f(o,i,j+1,k-1) f(o,i,j,k)=1+no​f(o,i,j,k)+ni​f(o+1,i−1,j,k)+nj​f(o,i+1,j−1,k)+nk​f(o,i,j+1,k−1)

n−onf(o,i,j,k)=1+inf(o+1,i−1,j,k)+jnf(o,i+1,j−1,k)+knf(o,i,j+1,k−1)\frac{n-o}{n}f(o,i,j,k)=1+\frac{i}{n}f(o+1,i-1,j,k)+\frac{j}{n}f(o,i+1,j-1,k)+\frac{k}{n}f(o,i,j+1,k-1) nn−o​f(o,i,j,k)=1+ni​f(o+1,i−1,j,k)+nj​f(o,i+1,j−1,k)+nk​f(o,i,j+1,k−1)

f(o,i,j,k)=ni+j+k+ii+j+kf(o+1,i−1,j,k)+ji+j+kf(o,i+1,j−1,k)+ki+j+kf(o,i,j+1,k−1)f(o,i,j,k)=\frac{n}{i+j+k}+\frac{i}{i+j+k}f(o+1,i-1,j,k)+\frac{j}{i+j+k}f(o,i+1,j-1,k)+\frac{k}{i+j+k}f(o,i,j+1,k-1) f(o,i,j,k)=i+j+kn​+i+j+ki​f(o+1,i−1,j,k)+i+j+kj​f(o,i+1,j−1,k)+i+j+kk​f(o,i,j+1,k−1)

这样就不存在状态相同的死循环转移了。

但是现在是 O(n4)O(n^4)O(n4) 的,需要进一步优化。

不难发现,盘子数量是固定不变的,即 o+i+j+k=no+i+j+k=no+i+j+k=n,所以当我们知道了其中任意三个数,就能推出剩下一个数。

设 f(i,j,k):f(i,j,k):f(i,j,k): 当前还剩下 i/j/ki/j/ki/j/k 个盘子中有 1/2/31/2/31/2/3 个寿司。
f(i,j,k)=ni+j+k+ii+j+kf(i−1,j,k)+ji+j+kf(i+1,j−1,k)+ki+j+kf(i,j+1,k−1)f(i,j,k)=\frac{n}{i+j+k}+\frac{i}{i+j+k}f(i-1,j,k)+\frac{j}{i+j+k}f(i+1,j-1,k)+\frac{k}{i+j+k}f(i,j+1,k-1) f(i,j,k)=i+j+kn​+i+j+ki​f(i−1,j,k)+i+j+kj​f(i+1,j−1,k)+i+j+kk​f(i,j+1,k−1)
最后还要注意循环枚举的细节:

  • kkk 只用了 k−1k-1k−1,当在 (i,j)(i,j)(i,j) 时会问到 j+1j+1j+1,所以 kkk 要在 jjj 循环的外层。
  • 同理 jjj 会用到同 kkk 下的 j+1j+1j+1,但此时是 i−1i-1i−1,所以 jjj 循环要在 iii 的外层。
  • 综上我们确定唯一的循环顺序是 k,j,ik,j,ik,j,i。

时间复杂度: O(n3)O(n^3)O(n3)。

code

#include <bits/stdc++.h>
using namespace std;
#define maxn 305
double f[maxn][maxn][maxn];
int a[5];
int n;
int main() {scanf( "%d", &n );for( int i = 1, x;i <= n;i ++ ) scanf( "%d", &x ), a[x] ++;for( int k = 0;k <= n;k ++ )for( int j = 0;j <= n;j ++ )for( int i = 0;i <= n;i ++ )if( i or j or k ) {if( i ) f[i][j][k] += f[i - 1][j][k] * i / (i + j + k);if( j ) f[i][j][k] += f[i + 1][j - 1][k] * j / (i + j + k);if( k ) f[i][j][k] += f[i][j + 1][k - 1] * k / (i + j + k);f[i][j][k] += n * 1.0 / (i + j + k);}  printf( "%.10f\n", f[a[1]][a[2]][a[3]] );return 0;
}

[AtCoder Educational DP Contest] J - Sushi(期望dp)相关推荐

  1. 【组合数学 dp[i][j] = a*dp[i, j-1] + b*dp[i-1,j]+c 求 dp[n][n]】Gym - 101480F Frightful Formula

    Step1 Problem: 已知 a , b , c a, b, c a,b,c 和 d p [ k ] [ 1 ] , d p [ 1 ] [ k ] dp[k][1], dp[1][k] dp[ ...

  2. 狂补dp Atcoder Educational DP Contest(全)

    狂补dp Atcoder Educational DP Contest(全) 注意 为了减少篇幅,本博客代码部分只放主代码部分,其余省略快读.快输.头文件等代码,即把代码看做伪代码更佳 A - Fro ...

  3. Atcoder Educational DP Contest 题解

    A - Frog 1/B - Frog 2 入门... 1 #include<cstdio> 2 #define abs(a) ((a)>=0?(a):(-(a))) 3 #defi ...

  4. [SCOI2008]奖励关(期望dp)

    你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再吃). 宝 ...

  5. AtCoder AGC007E Shik and Travel (二分、DP、启发式合并)

    题目链接 https://atcoder.jp/contests/agc007/tasks/agc007_e 题解 首先有个很朴素的想法是,二分答案\(mid\)后使用可行性DP, 设\(dp[u][ ...

  6. [NOIP2016]换教室(概率期望$DP$)

    其实吧我老早就把这题切了--因为说实话,这道题确实不难啊--李云龙:比他娘的状压DP简单多了 今天我翻以前在Luogu上写的题解时,突然发现放错代码了,然后被一堆人\(hack\)--蓝瘦啊\(ORZ ...

  7. POJ 2096 Collecting Bugs:期望dp

    题目链接:http://poj.org/problem?id=2096 题意: 有一个程序猿,他每天都会发现一个bug. bug共有n个种类.属于某一个种类的概率为1/n. 有s个子系统,每个bug属 ...

  8. 插头DP 概率DP / 期望DP

    插头DP && 概率DP / 期望DP 写在前面: 插头DP P5056 [模板]插头dp 手写哈希表的方法: 拉链法的代码如下: 开放寻址法的代码如下: 接下来是这道题的代码实现: ...

  9. ACM概率期望dp刷题总结

    这个周刷了很多概率期望有关的dp题目,缘起2016青岛D题和取log的神操作题HDU 5988 2016青岛区域赛 (最小费用流) 这类题目没有固定的模板,而且概率可以很容易插入一些经典模型,比如下面 ...

最新文章

  1. 物理机linux无法上网,物理机不能访问虚拟机VMNet8中的Linux
  2. deepin linux桌面设置,Deepin系统的桌面样式:高效模式和时尚模式
  3. 德国市占率第一的科沃斯携最新扫地机器人亮相IFA展
  4. SpringBoot整合Security安全框架、控制权限
  5. 单例设计模式-序列化破坏单例模式原理解析及解决方案
  6. RabbitMQ系列教程之一:我们从最简单的事情开始!Hello World
  7. OpenStack精华问答 | OpenStack的网络类型有哪些?
  8. ftp上传乱码_ftp同步图片到本地文件夹,ftp同步图片到本地文件夹的实现步骤
  9. The partial sum problem
  10. idea开发springboot的一些小干货
  11. php创建游戏房间思路,用Swoole来写个联机对战游戏呀!(八)创建游戏房间
  12. matlab数据变成一列数据,用MATLAB处理EXCEL中一列共100000个数据,请问如何将数据导入并将数据做正态曲线拟合...
  13. Linux下安装PyQt4
  14. eclipse运行不了jsp代码,错误代码:couldn't create the java virtual machine. a fatal exception has occurred.
  15. 世界各个国家或地区国际域名缩写(Countries and Regions)
  16. delphi调用dll
  17. python模板注入_BUUCTF/护网杯 easy_tornado 模板注入
  18. 拓嘉启远电商:拼多多如何完美避开历史最低价
  19. Android测试solo,SoloPi支付宝开源的 Android 专项测试工具的介绍与快速上手
  20. 【硬件】AD623单电源供电差分放大

热门文章

  1. mysql 堆叠查询_SQL 注入方法 - 盲注、报错注入、UNION查询注入与堆叠注入
  2. php psr 编码规范_PHP之PSR-4规范:自动加载
  3. sql 百分数_SQL经典50题笔记
  4. lua loadstring传递参数_lua学习之函数篇
  5. python的所有库_Python 常用库
  6. spring boot jar包_「Spring Boot 新特性」 jar 大小自动瘦身
  7. python os rename用法_Python os.rename() 方法
  8. 计算机语言学考研科目,语言学考研笔记整理(共16页)
  9. js重新渲染div_前端工程师必备:从浏览器的渲染到性能优化
  10. [蓝桥杯2017初赛]纸牌三角形-枚举permutation+数论