好久之前学过,记得是一次亚洲区的前几天看了看概率dp,然后亚洲区就出了一道概率dp,当时虽然做上了,但是感觉有很多地方没懂,今天起早温习了一下,觉得很多地方茅塞顿开,果然学习的话早上效果最好了。

首先来看一道最基础概率dp

题意是,有一个软件,有s个子系统,会产生n种bug。 
某个程序员一天能发现一个bug,这个bug是这n种bug中的一种,然后发生在某个子系统中。 
问,找到所有的n种bug,且每个子系统都找到bug,这样所要的天数,的期望。

期望,可以分解成多个子期望的加权和,权为子期望发生的概率 
所以: 我首先想到了一个这样的公式dp[x][y] = dp[x][y]*p1+dp[x-1][y-1]*p2+dp[x][y-1]*p3+dp[x-1][y]*p4

dp[x][y]代表已经有x种bug并且有y个系统至少有一个bug的期望值

我们知道他是从自身以及他的前几种状态推导过来,乍一看这个公式应该是对的,但是dp[n][m]会无穷大,因为他的期望是没有停止状态的,也就是题意要求的应该是到达n,m状态时停止。

那么我们又可以从倒推的角度去考虑这个问题,dp[x][y]表示的是已经有x种bug并且有y个系统至少有一种bug的时候还需要多少步能够到达dp[n][m]的状态。

那么公式又变成了这样dp[x][y] = dp[x+1][y+1]*p1+dp[x+1][y]*p2+dp[x][y+1]*p3+dp[x][y]*p4+1

也就是dp[x][y] = dp[x+1][y+1] *(n-x)*(m-y)/n/m+dp[x+1][y]*(n-x)*y/n/m+dp[x][y+1]*x*(m-y)/n/m+dp[x][y]*x*y/n/m+1

将dp[x][y]合并得dp[x][y](1-x*y/n/m) = dp[x+1][y+1] *(n-x)*(m-y)/n/m+dp[x+1][y]*(n-x)*y/n/m+dp[x][y+1]*x*(m-y)/n/m+1

1.poj2096,就是上面的题

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
double dp[][];
int main(){
int n, m;
scanf("%d%d", &n, &m);
for(int i = ;i <= n+; i++){
for(int k = ; k <= m+; k++){
dp[i][k]= ;
}
}
for(int x = n; x >= ; x--){
for(int y = m; y >=; y--){
if(x == n && y ==m)dp[x][y] = ;
else
dp[x][y]= (+dp[x+][y+] *(n-x)*(m-y)/n/m+dp[x+][y]*(n-x)*y/n/m+dp[x][y+]*x*(m-y)/n/m)/(1.0-1.0*x*y/n/m);
}
}
printf("%.4f\n", dp[][]);
}

2.UVALive 5811

题目大意:有54张牌,一张一张翻,在四种花色都不小于分别给定的四个值时停止,王牌可以当做任意一种花色,但是在翻得时候就要确定,求翻牌数的期望。

公式神马的好推,写的时候稍微费劲了点

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
double dp[][][][][][];
int main(){
int t;
scanf("%d", &t);
int cas = ;
while(t--){
int a, b, c, d;
scanf("%d%d%d%d", &a, &b, &c, &d);
int aa = ;
if(a > ) aa += -a;
if(b > ) aa += -b;
if(c > ) aa += - c;
if(d > ) aa += - d;
if(aa < -){
printf("Case %d: %.3f\n", cas++, -1.0);//printf("000");
continue;
}
for(int i = ; i >= ; i--){
for(int k = ; k >= ;k --){
for(int j = ; j >= ; j--){
for(int h = ; h >= ; h--){
for(int x = ; x >= ; x--){
for(int y = ; y >= ; y--){
int aa = i, bb = k, cc = j, dd = h;
if(x == ) aa++;
if(x == ) bb ++;
if(x == ) cc++;
if(x == ) dd++;
if(y == ) aa++;
if(y==) bb++;
if(y == ) cc++;
if(y == ) dd++;
int tot = - aa - bb - cc- dd;
if(aa >= a && bb >= b && cc >= c && dd >= d){
dp[i][k][j][h][x][y] = ;continue;
}else if(tot == ){
dp[i][k][j][h][x][y] = ;continue;
}
double uu = ;
int ss = ; //kexuanwangpai
if(!x) ss ++;
if(!y) ss ++;
dp[i][k][j][h][x][y] = ;
if(!x){
uu = min(min(min(dp[i][k][j][h][][y], dp[i][k][j][h][][y]), dp[i][k][j][h][][y]), dp[i][k][j][h][][y]);
//if(i+k+j+h == 52 && x == 0 && y == 0) printf("%.3lf %.3lf-----------\n", uu,ss*1.0/tot*uu);
dp[i][k][j][h][x][y] += ss*1.0/tot*uu;
}
else if(!y){
uu = min(min(min(dp[i][k][j][h][x][],dp[i][k][j][h][x][]),dp[i][k][j][h][x][]), dp[i][k][j][h][x][]);
dp[i][k][j][h][x][y] += ss * 1.0/tot*uu;
}
uu = ;
if(i < ){
uu += dp[i+][k][j][h][x][y]*(-i)/tot;
}
if(k < )
uu +=dp[i][k+][j][h][x][y] * (-k)/tot;
if(j < )
uu += dp[i][k][j+][h][x][y] *( - j)/tot;
if(h < )
uu += dp[i][k][j][h+][x][y] * ( - h)/tot;
dp[i][k][j][h][x][y] += uu;
}
}
}
}
}
}
//printf("%.3lf\n", dp[13][13][13][13][0][0]);
printf("Case %d: %.3f\n", cas++, dp[][][][][][]);
}
}

概率dp小结的更多相关文章

  1. 概率及期望DP小结

    资源分享 26 个比较概率大小的问题 数论小白都能看懂的数学期望讲解 概念 \(PS\):不需要知道太多概念,能拿来用就行了. 定义 样本(\(\omega\)):一次随机试验产生的一个结果. 样本空 ...

  2. Codeforces 28C [概率DP]

    /* 大连热身D题 题意: 有n个人,m个浴室每个浴室有ai个喷头,每个人等概率得选择一个浴室. 每个浴室的人都在喷头前边排队,而且每个浴室内保证大家都尽可能均匀得在喷头后边排队. 求所有浴室中最长队 ...

  3. HDU 4405 Aeroplane chess (概率DP)

    题意:你从0开始,要跳到 n 这个位置,如果当前位置是一个飞行点,那么可以跳过去,要不然就只能掷骰子,问你要掷的次数数学期望,到达或者超过n. 析:概率DP,dp[i] 表示从 i  这个位置到达 n ...

  4. POJ 2096 Collecting Bugs (概率DP)

    题意:给定 n 类bug,和 s 个子系统,每天可以找出一个bug,求找出 n 类型的bug,并且 s 个都至少有一个的期望是多少. 析:应该是一个很简单的概率DP,dp[i][j] 表示已经从 j ...

  5. POJ 2151 Check the difficulty of problems (概率DP)

    题意:ACM比赛中,共M道题,T个队,pij表示第i队解出第j题的概率 ,求每队至少解出一题且冠军队至少解出N道题的概率. 析:概率DP,dp[i][j][k] 表示第 i 个队伍,前 j 个题,解出 ...

  6. 概率DP light oj 1030

    t组数据 n块黄金 到这里就捡起来 出发点1 到n结束  点+位置>n 重掷一次 dp[i] 代表到这里的概率 dp[i]=(dp[i-1]+dp[i-2]... )/6  如果满6个的话 否则 ...

  7. hdu 4050 2011北京赛区网络赛K 概率dp ***

    题目:给出1-n连续的方格,从0开始,每一个格子有4个状态,左右脚交替,向右跳,而且每一步的步长必须在给定的区间之内.当跳出n个格子或者没有格子可以跳的时候就结束了,求出游戏的期望步数 0:表示不能到 ...

  8. [转]概率DP总结 by kuangbin

    概率类题目一直比较弱,准备把kuangbin大师傅总结的这篇题刷一下! 我把下面的代码换成了自己的代码! 原文地址:http://www.cnblogs.com/kuangbin/archive/20 ...

  9. SGU 422 Fast Typing(概率DP)

    题目大意 某人在打字机上打一个字符串,给出了他打每个字符出错的概率 q[i]. 打一个字符需要单位1的时间,删除一个字符也需要单位1的时间.在任意时刻,他可以花 t 的时间检查整个打出来的字符串,并且 ...

随机推荐

  1. PHPCMS v9 在windows2008系统 IIS7 下设置伪静态的方法

    安装环境:windows2008+IIS7.0+PHP5+MYSQL5 一.安装phpcms v9程序,设置伪静态.如图: 二.安装IIS7官方Url重写模块 1.先到IIS官方下载模块 下载地址:h ...

  2. 【转】基于jquery的无刷新表格分页

    效果图 css样式 <style> html,body{margin: 0;padding:0} a:focus {outline: none;} /* 通用表格显示 */ table, ...

  3. ServerInfo.INI解密

    [GlobalInfo]LastServerName=000781ED2D127FBA074D97444DC82F216443034E66BB341A428B14E326A656B9LastServe ...

  4. Ubuntu等Linux系统清除DNS缓存的方法

    buntu等Linux系统清除DNS缓存的方法 直接说方法: 如果系统下有nscd,那么就直接 sudo /etc/init.d/nscd restart 如果没有也没关系,网上接受的方法大都是 su ...

  5. 三元运算和lambda表达式

      19.三目运算,三元运算:     if else 的简写: name = 'alex' if 1 == 1 else 'SB'   ==> 等价于      if 1 == 1:     ...

  6. 为何某些公司不允许使用C++ STL?

    说几个STL的缺点吧,虽然都是在比较极端的情况下出现,但是对于一些大项目还是会遇到的 1. 代码膨胀问题每一个实例化过的模板类,都会膨胀出一份独立的代码,比如std::vector<std::s ...

  7. google开源的C++性能分析工具 - gperftools

    gperftools是Google提供的一套工具,其中的一个功能是CPU profiler,用于分析程序性能,找到程序的性能瓶颈. 安装 gperftools:http://code.google.c ...

  8. JQuery 插件 - 弹窗:BlockUI

    JQuery的弹窗插件,网上实在有很多做的比较好的,比如artDialog.layer,甚至EasyUI等等.这些在效果上做的非常好.但我觉得一个小小的弹窗提示,没有必要引用这些(其实是有点大材小用了 ...

  9. .net 面试题(3)

    96.题目: 活期存款中,"储户"通过"存取款单"和"储蓄所"发生联系.假定储户包括:账号,姓名,电话,地址,存款额:"储蓄所&q ...

  10. js中的循环语句

    js中的循环语句可分为三种:1.while:2.do……while:3.for. while的语法为 while (exp) {    //statements;} var a=1,b=0; whil ...