题目链接

题意:

    给一个文档, 这个文档由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)

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

    

 double dp(int n, int y, int a)
{
if (n == ) // There are no options to choose
return ;
double p_no = (n - y) / (double) n;
double p_yes = y / (double) n;
double ans = ;
if (y < n)
ans += (dp(n - , y, ) + (a != )) * p_no;
if (y > )
ans += (dp(n - , y - , ) + (a != )) * p_yes;
return ans;
}

代码:

    

 #include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <iostream>
#include <algorithm>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define eps 1e-6
#define MAXN 5050
int n, s;
double dp[][MAXN][];// 0 --> NO, 1 --> yes
int yes_num, no_num;
int kcase = ;
void solve()
{
memset(dp, , sizeof(dp));
yes_num = s - * n;
no_num = n - yes_num;
for(int i = ; i <= n + ; i ++)
for(int j = ; j <= min(i, yes_num); j ++)
{
double p_yes = j * 1.0 / i;
double p_no = (i - j) * 1.0 / i; if(j - >= )
{
dp[i % ][j][] = dp[(i + ) % ][j - ][] * p_yes + (dp[(i + ) % ][j][] + 1.0) * p_no;
dp[i % ][j][] = (dp[(i + ) % ][j - ][] + 1.0) * p_yes + dp[(i + ) % ][j][] * p_no;
}
else
{
dp[i % ][j][] = (dp[(i + ) % ][j][] + 1.0) * p_no;
dp[i % ][j][] = dp[(i + ) % ][j][] * p_no;
}
}
printf("Case %d: %.7lf\n", ++kcase, dp[n % ][yes_num][]);
}
void solve_()
{
memset(dp, , sizeof(dp));
yes_num = s - * n;
no_num = n - yes_num; for(int i = n - ; i >= ; i --)
for(int j = min(i, yes_num); j >= && (i - j <= no_num); j --)
{
double p_yes = (yes_num - j) * 1.0 / (n - i);
double p_no = (no_num - (i - j)) * 1.0 / (n - i); if(j + <= yes_num)
{
dp[i % ][j][] = (dp[(i + ) % ][j + ][] + 1.0) * p_yes + dp[(i + ) % ][j][] * p_no;
dp[i % ][j][] = dp[(i + ) % ][j + ][] * p_yes + (dp[(i + ) % ][j][] + 1.0) *p_no;
}
else
{
dp[i % ][j][] = p_yes + dp[(i + ) % ][j][] * p_no;
dp[i % ][j][] = (dp[(i + ) % ][j][] + 1.0) *p_no;
}
}
printf("Case %d: %.7lf\n", ++kcase, dp[][][]);
} int main()
{
int T;
scanf("%d", &T);
while(T --)
{
scanf("%d %d", &n, &s);
solve_();
}
return ;
}

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. Highcharts可拖动式图表

    Highcharts可拖动式图表 默认情况下,Highcharts依据给定的数据列生成图表. 浏览者是无法改动图表的. 假设浏览者须要手动调整数据节点.就须要借助第三方插件Draggable Poin ...

  2. 基于Shading Model(对光照变化一定不变性)的运动目标检测算法

    光照模型(Shading Model)在很多论文中得到了广泛的应用,如robust and illumination invariant change detection based on linea ...

  3. 聊一聊 Android 6.0 的运行时权限

    权限一刀切 棉花糖运行时权限 权限的分组 正常权限 正常权限列表 特殊权限危险权限 请求SYSTEM_ALERT_WINDOW 请求WRITE_SETTINGS 必须要支持运行时权限么 不支持运行时权 ...

  4. 使用java进行文件编码转换

    在开发过程中,可能会遇到文件编码的转换,尽管说开发工具eclipse能够转换编码,可是有的情况却非常不方便.比方,原来文件本身的编码是GBK,如今要转换成UTF-8,假设直接在eclipse中把文件编 ...

  5. php的ob_flush和flush(转)

    php.ini中 output_buffering = off 关闭php的缓存 implicit_flush = Off php不会立即输出到浏览器.如果是ON,相当于每次ECHO 立刻执行一个FL ...

  6. Android菜单详解(四)——使用上下文菜单ContextMenu

    之前在<Android菜单详解(二)——创建并响应选项菜单>和<Android菜单详解(三)——SubMenu和IconMenu>中详细讲解了选项菜单,子菜单和图标菜单.今天接 ...

  7. 局域网内使用linux的ntp服务

    假设我们的饿局域网无法连接外网,但又需要同步时间,怎么办? 1. 已局域网内的一台机器作为基础,适用date修改其他机器的时间,date -s ...,很不方便,这里不介绍. 2. 适用ntp服务,自 ...

  8. RedHat7上安装MariaDB

    编译安装MariaDB 下载MariaDB# wget http://mirrors.opencas.cn/mariadb//mariadb-10.1.8/source/mariadb-10.1.8. ...

  9. DataDictionaryTool 一款生成数据库字典工具支持mysql和oracle

    因为常常查看mysql数据结构,频繁操作.很不爽,于是想把数据表制作成数据字典,于是网上搜的一款工具 DataDictionaryTool ,最终制作成功,分享给大家! 1,此工具需要安装jre ,简 ...

  10. asp.net mvc+web api+easyui

    前奏:第一次写博客,记录一下学习和开发的过程. 现在写的是一个后台管理系统,有基本的权限功能,其他功能都可以扩展.用到的技术是 asp.net mvc5,web api 2,entityframewo ...