题目链接

题意:

    给一个文档, 这个文档由yes 、no 组成, 共有s个byte, 共有n个yes、no。

    假设yes的个数为yes_num, no的个数为no_num。

    将这n个数进行排列, 对于每个排列, 将其右移一个结果, 并在最左端补上yes, 再将其与原排列进行对比, 看有多少个不同的。

    计算所有排列中 不同结果的平均次数。

思路:

    可能题意说的不是很清楚, 这里抽象一下, 将yes用1代替, no用0代替。

    当n = 3, s = 7时, 也就是2个0 一个1, 有下面三种排列

    100, 010, 001

    对于每种排列的处理:

    100

    110 不同的只有一个, 有三种情况, 每种情况抽中的概率是1/3 所以 当前情况的期望就是 1/3 * 1

    

    010

    101 不同的有三个, 当前情况的期望是1/3 * 3

  

    001

    100 不同的有两个,当前情况的期望是1/3 * 2

    so, 总的期望就是1/3 * (1+3+2) = 6 / 3 = 2

    

    将原排列进行整理下, 会发现一个现象。

    每种排列的次数就是原排列中有多少个相邻不同的数字, 如果最左端是0, 那么还要 + 1 (因为左端要补上1, 和0 不同 所以要加1)

    此时可以发现, 当前状态的期望数其实和上一状态是有关系的。

    假设dp[i][j][flag]为当前为第i位, 前面有j个1(yes), 上一状态(第i + 1 位) 是flag(0 == no, 1 == yes)。

    那么, flag 要么为0, 要么为一, 也即 第i + 1位的状态。

    {……j 个 yes……} flag k {…………}, k为第i + 2 位的状态。

    dp[i][j][flag] = (dp[i+1][j][0] + (flag != 0))* p_no + (dp[i + 1][j + 1] + (flag != 1)) * p_yes.

    

    也有大神推出公式了, 不过在下实在推不出来 囧 坐等大神解答。

    公式:(2.0 * yes_num * no_num + no_num)/(yes_num + no_num)

    加一段递归代码用以理解状态转移方程。

    

  1. double dp(int n, int y, int a)
  2. {
  3. if (n == ) // There are no options to choose
  4. return ;
  5. double p_no = (n - y) / (double) n;
  6. double p_yes = y / (double) n;
  7. double ans = ;
  8. if (y < n)
  9. ans += (dp(n - , y, ) + (a != )) * p_no;
  10. if (y > )
  11. ans += (dp(n - , y - , ) + (a != )) * p_yes;
  12. return ans;
  13. }

代码:

    

  1. #include <cmath>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <cstdlib>
  5. #include <ctime>
  6. #include <set>
  7. #include <map>
  8. #include <list>
  9. #include <queue>
  10. #include <string>
  11. #include <vector>
  12. #include <fstream>
  13. #include <iterator>
  14. #include <iostream>
  15. #include <algorithm>
  16. using namespace std;
  17. #define LL long long
  18. #define INF 0x3f3f3f3f
  19. #define MOD 1000000007
  20. #define eps 1e-6
  21. #define MAXN 5050
  22. int n, s;
  23. double dp[][MAXN][];// 0 --> NO, 1 --> yes
  24. int yes_num, no_num;
  25. int kcase = ;
  26. void solve()
  27. {
  28. memset(dp, , sizeof(dp));
  29. yes_num = s - * n;
  30. no_num = n - yes_num;
  31. for(int i = ; i <= n + ; i ++)
  32. for(int j = ; j <= min(i, yes_num); j ++)
  33. {
  34. double p_yes = j * 1.0 / i;
  35. double p_no = (i - j) * 1.0 / i;
  36.  
  37. if(j - >= )
  38. {
  39. dp[i % ][j][] = dp[(i + ) % ][j - ][] * p_yes + (dp[(i + ) % ][j][] + 1.0) * p_no;
  40. dp[i % ][j][] = (dp[(i + ) % ][j - ][] + 1.0) * p_yes + dp[(i + ) % ][j][] * p_no;
  41. }
  42. else
  43. {
  44. dp[i % ][j][] = (dp[(i + ) % ][j][] + 1.0) * p_no;
  45. dp[i % ][j][] = dp[(i + ) % ][j][] * p_no;
  46. }
  47. }
  48. printf("Case %d: %.7lf\n", ++kcase, dp[n % ][yes_num][]);
  49. }
  50. void solve_()
  51. {
  52. memset(dp, , sizeof(dp));
  53. yes_num = s - * n;
  54. no_num = n - yes_num;
  55.  
  56. for(int i = n - ; i >= ; i --)
  57. for(int j = min(i, yes_num); j >= && (i - j <= no_num); j --)
  58. {
  59. double p_yes = (yes_num - j) * 1.0 / (n - i);
  60. double p_no = (no_num - (i - j)) * 1.0 / (n - i);
  61.  
  62. if(j + <= yes_num)
  63. {
  64. dp[i % ][j][] = (dp[(i + ) % ][j + ][] + 1.0) * p_yes + dp[(i + ) % ][j][] * p_no;
  65. dp[i % ][j][] = dp[(i + ) % ][j + ][] * p_yes + (dp[(i + ) % ][j][] + 1.0) *p_no;
  66. }
  67. else
  68. {
  69. dp[i % ][j][] = p_yes + dp[(i + ) % ][j][] * p_no;
  70. dp[i % ][j][] = (dp[(i + ) % ][j][] + 1.0) *p_no;
  71. }
  72. }
  73. printf("Case %d: %.7lf\n", ++kcase, dp[][][]);
  74. }
  75.  
  76. int main()
  77. {
  78. int T;
  79. scanf("%d", &T);
  80. while(T --)
  81. {
  82. scanf("%d %d", &n, &s);
  83. solve_();
  84. }
  85. return ;
  86. }

LightOj_1274 Beating the Dataset的更多相关文章

  1. LightOJ - 1274 Beating the Dataset —— 期望

    题目链接:https://vjudge.net/problem/LightOJ-1274 1274 - Beating the Dataset    PDF (English) Statistics ...

  2. 【非原创】LightOJ-1274 Beating the Dataset【期望dp】

    学习博客:戳这里

  3. KUANGBIN带你飞

    KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题    //201 ...

  4. kuangbin 带你飞 概率期望

    正推不行就逆推! 经典问题:生日悖论 换成其互斥事件:m个人, 每个人生日都不相同的概率 ≤ 0.5 时最小人数. 这就是邮票收集问题的变形:每个邮票至少出现一次的概率 小于等于 0.5 邮票收集问题 ...

  5. [kuangbin带你飞]专题1-23题目清单总结

    [kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...

  6. ACM--[kuangbin带你飞]--专题1-23

    专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 FliptilePOJ 1426 Find T ...

  7. HTML5 数据集属性dataset

    有时候在HTML元素上绑定一些额外信息,特别是JS选取操作这些元素时特别有帮助.通常我们会使用getAttribute()和setAttribute()来读和写非标题属性的值.但为此付出的代价是文档将 ...

  8. C#读取Excel,或者多个excel表,返回dataset

    把excel 表作为一个数据源进行读取 /// <summary> /// 读取Excel单个Sheet /// </summary> /// <param name=& ...

  9. DataTable DataRow DataColumn DataSet

    1.DataTable 数据表(内存) 2.DataRow DataTable 的行 3.DataColumn DataTable 的列 4.DataSet 内存中的缓存

随机推荐

  1. Python调用C可执行程序(subprocess) 分类: python 服务器搭建 C/C++ shell 2015-04-13 21:03 87人阅读 评论(0) 收藏

    从Python 2.4开始,Python引入subprocess模块来管理子进程,以取代一些旧模块的方法:如 os.system.os.spawn.os.popen.popen2.commands. ...

  2. 1032 - Intersecting Dates

    A research group is developing a computer program that will fetch historical stock market quotes fro ...

  3. 第一个Xcode项目 - 代码修改布局约束

    第一行的选中效果已经有了,那第二行的选中效果怎么做呢?我这里选择改变布局约束来实现选中效果 [我有个用object-c做APP的同事他说,我觉得这个应该去获取色块的位置,然后赋给选中用的View,然后 ...

  4. STM32的优先级NVIC_PriorityGroupConfig的理解及其使用

    写作原由:因为之前有对stm32 优先级做过研究,但是没时间把整理的东西发表,最近项目需要2个串口,但是不是两个串口同时使用,只是随机使用其中一个,程序对2个串口的优先级需要配置: 此文思路:“中断优 ...

  5. git的一些基础命令

    Git常用命令 请确保已经安装里git客户端 一般配置 git --version //查看git的版本信息 git config --global user.name //获取当前登录的用户 git ...

  6. JS获取图片上传地址

    function getObjectURL(file) { var url = null ; if (window.createObjectURL!=undefined) { // basic url ...

  7. ubuntu15.10下sublime text3 无法输入中文解决办法

    原文链接:http://geek.csdn.net/news/detail/44464 1.首先保证你的电脑有c++编译环境 如果没有,通过以下指令安装 sudo apt-get install bu ...

  8. 使用微信js接口的方法 ,以调用相机为例

    protected string GetTimeStamp_Str=""; protected string nonceStr_Str = ""; protec ...

  9. asp.net 调用前台JS调用后台,后台掉前台JS

    C#前台js调用后台代码前台js<script type="text/javascript" language="javascript"> func ...

  10. JQM 页面滚动加载

    1 应用场景:文章比较长,只加载部分,当到页面底部触发获取更多数据. 2 如图,监听滚动条的位置,触发事件,转化为求X的长度, 3 实例代码: //滚动条到底加载更多 $(document).on(& ...