LightOj_1274 Beating the Dataset
题意:
给一个文档, 这个文档由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的更多相关文章
- LightOJ - 1274 Beating the Dataset —— 期望
题目链接:https://vjudge.net/problem/LightOJ-1274 1274 - Beating the Dataset PDF (English) Statistics ...
- 【非原创】LightOJ-1274 Beating the Dataset【期望dp】
学习博客:戳这里
- KUANGBIN带你飞
KUANGBIN带你飞 全专题整理 https://www.cnblogs.com/slzk/articles/7402292.html 专题一 简单搜索 POJ 1321 棋盘问题 //201 ...
- kuangbin 带你飞 概率期望
正推不行就逆推! 经典问题:生日悖论 换成其互斥事件:m个人, 每个人生日都不相同的概率 ≤ 0.5 时最小人数. 这就是邮票收集问题的变形:每个邮票至少出现一次的概率 小于等于 0.5 邮票收集问题 ...
- [kuangbin带你飞]专题1-23题目清单总结
[kuangbin带你飞]专题1-23 专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 Fli ...
- ACM--[kuangbin带你飞]--专题1-23
专题一 简单搜索 POJ 1321 棋盘问题POJ 2251 Dungeon MasterPOJ 3278 Catch That CowPOJ 3279 FliptilePOJ 1426 Find T ...
- HTML5 数据集属性dataset
有时候在HTML元素上绑定一些额外信息,特别是JS选取操作这些元素时特别有帮助.通常我们会使用getAttribute()和setAttribute()来读和写非标题属性的值.但为此付出的代价是文档将 ...
- C#读取Excel,或者多个excel表,返回dataset
把excel 表作为一个数据源进行读取 /// <summary> /// 读取Excel单个Sheet /// </summary> /// <param name=& ...
- DataTable DataRow DataColumn DataSet
1.DataTable 数据表(内存) 2.DataRow DataTable 的行 3.DataColumn DataTable 的列 4.DataSet 内存中的缓存
随机推荐
- 数位DP问题整理(一)
第一题:Amount of degrees (ural 1057) 题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1057 题意:[x,y ...
- Android 获取运营商信息(完整版)-解决高通,MTK等双卡问题
由于国内的运营商问题,双卡手机获取IMSI号问题要根据厂商API 来实现. 下面我们就来做一套完整的分析运营商获取IMSI号逻辑. 1,首先我们要判断手机的平台. 1.1,判断手机是否MTK平台 1 ...
- Linux性能及调优指南(翻译)
http://blog.csdn.net/ljianhui/article/details/46718835 http://blog.chinaunix.net/uid-26000296-id-406 ...
- Servlet 工作原理解析--转载
原文:http://www.ibm.com/developerworks/cn/java/j-lo-servlet/index.html?ca=drs- Web 技术成为当今主流的互联网 Web 应用 ...
- oracle在敏感操作前创建还原点
我们都知道,在vmware虚拟机中有一个拍摄快照的功能,我们可以把系统此时的状态保存下来,一方后面遇到不测事件,也好将系统还原,oracle中也有类似功能. 首先创建一张学生表: 向学生表中插入一条数 ...
- 分分钟教你集成沉浸式侧滑关闭Activity
网上搜索侧滑关闭Activity,几乎没有系统状态栏跟随页面一起联动的,有明显的撕裂感,而这里则是状态栏跟随页面联动的,说来集成也是简单,等会你就知道了. 个人习惯,写博客前喜欢先截图 1.首先以项目 ...
- 使用SBT构建Scala项目
既然决定要在Scala上下功夫,那就要下的彻底.我们入乡随俗,学一下SBT.sbt使用ivy作为库管理工具.ivy默认把library repository建在user home下面. 安装SBT 在 ...
- Crawler & Ajax:WebBrowser C#
Crawler 與 Ajax http://net.zdnet.com.cn/network_security_zone/2007/1005/536329.shtml WebBrowser: 利用We ...
- javascript 之闭包-理解不了来找我
1,闭包是什么 (百度百科定义)--闭包是可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变 量).“闭包” 一词 ...
- Perl连接Sqlite数据库
Sqlite是一个小巧的嵌入式关系型数据库,几乎可以嵌入所有编程语言,特别是C,C++,PHP,Perl等.这里就介绍如何用Perl连接并操作Sqlite数据库. use DBI; # perl用以操 ...