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 内存中的缓存
随机推荐
- CoreJava_线程并发(堵塞队列):在某个目录下搜索含有某keyword的文件
Java多线程编程是很考验一个程序猿水平的. 传统的WEB程序中.由于框架提供了太多的健壮性.并发性.可靠性的支持,所以我们都是将全部的注意力放到了业务实现上.我们不过依照业务逻辑的要求.不停的积累自 ...
- 【转】android的startActivityForResult学习心得
http://blog.csdn.net/yanzi1225627/article/details/7800529 从昨晚到现在终于调试通了一个startActivityForResult的例子,网上 ...
- hdu2044java递推
一只小蜜蜂... Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
- Android BLE开发——Android手机与BLE终端通信初识
蓝牙BLE官方Demo下载地址: http://download.csdn.net/detail/lqw770737185/8116019参考博客地址: http://www.eoeandr ...
- 使用泛型定义一个可重用的Dao
dao用来和数据库进行交互,一个项目中,可能有用户表,产品表等等,不可能为每一个表都建立一个dao,使用泛型可以实现通吃. UserDao.java public class UserDao < ...
- 文件MD5查看器工具与源码实现及下载
由于工作中经常需要查看文件的MD5值,先前网上找了几个MD5值查看工具,但基本都是选择文件,还没有复制功能,于是今天我就自己编写了个MD5查看工具,支持文件拖拽查看,并可以复制功能. 由于本工具比较小 ...
- Google Map API v2 (四)----- 导航路径
仍然是建议个异步小任务 private GetPathTask mGetPathTask = null; private void getGuidePath(LatLng origin){ if(mG ...
- springmvc使用@ResponseBody返回json乱码解决方法
1.springmvc 3.2以上的版本解决乱码的方法: 第一步:在配置中加入: <mvc:annotation-driven> <mvc:message-converters re ...
- Linq扩展方法之All 、Any
// Summary: // 确定序列中的所有元素是否满足条件. // Parameters: // source:包含要应用谓词的元素的 System.Collections.Generic.IEn ...
- 24、Javascript BOM
BOM(Browser Object Model)浏览器对象模型,一组浏览器提供的API. window对象 window对象表示当前浏览器的窗口,是Javascript的顶级对象,所有创建的对象.函 ...