题目链接

题意:

    给一个文档, 这个文档由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. .NET DataTable转化为json格式

    标准的json用“分隔,不用' public static string DataSetToJson(DataTable dt) {        string json = string.Empty ...

  2. 安卓开发中Theme.AppCompat.Light的解决方法

    styles.xml中<style name="AppBaseTheme" parent="Theme.AppCompat.Light">提示如下错 ...

  3. Nginx的事件处理机制

    Nginx的事件处理机制:对于一个主要的webserver来说,事件通常有三种类型,网络事件.信号.定时器. 首先看一个请求的基本过程:建立连接---接收数据---发送数据 .再次看系统底层的操作 : ...

  4. 基于物联网技术和RFID电子客票的铁路自己主动检票机

    前言: RFID电子客票具有检阅速度快.信息量大.安全性高和高速物理定位的独特优势,随着标准的统一和成本的减少,它在铁路上有着巨大的应用前景,同一时候鉴于车站对物联网化的需求,我们设想出新一代的检票机 ...

  5. cocos2dx 以子弹飞行为例解说拖尾效果类CCMotionStreak

    在游戏开发中,有时会须要在某个游戏对象上的运动轨迹上实现渐隐效果.比方子弹的运动轨迹,假设不借助引擎的帮助,这样的效果则须要通过大量的图片来实现.而Cocos2D-x的拖动渐隐效果类CCMotionS ...

  6. pugixml

    http://www.firedragonpzy.com.cn/index.php/archives/3227 有关cocos2d-x的xml文件读取问题

  7. Ⅴ.AngularJS的点点滴滴-- 资源和过滤

    资源ngResource(依赖ngResource模块) <html> <script src="http://ajax.googleapis.com/ajax/libs/ ...

  8. sum() over() 函数的使用

    over不能单独使用,要和分析函数:rank(),dense_rank(),row_number(),sum()等一起使用. over函数的参数:over(partition by columnnam ...

  9. 前后端分离--mock

    fekit mock 数据 > fekit server -m mock.config 配置mock.config 支持正则 module.exports = { /queryProductDe ...

  10. 配置toad进行导入导出数据库操作

    最近需要对oracle进行导入导出操作,于是研究使用toad进行导入导出oracle数据库操作,现稍作记录. oracle的导入导出不管是否使用toad还是pl/sql工具进行操作,实际上最终都是通过 ...