期望dp专题
一直不明白为什么概率是正推,期望是逆推。 现在题目做多了,慢慢好像有点明白了
poj2096
收集bug, 有n个种类的bug,和s个子系统。 每找到一个bug需要一天。
要我我们求找到n个种类的bug,且在每个系统中都找到一个bug的期望天数
设dp[i][j] 为找到i个种类的bug和在j个系统中找到bug后,还需要的期望天数
那么dp[n][s] 肯定是0,而dp[0][0]是我们要求的。 这也就是为什么期望是要逆推。
还有一点就是这一状态的期望会等于 所有(下一状态的的期望*这一状态走向下一状态的概率)的和+1
所有可能的情况如下
找到了一个新种类的bug (n-i)/n 第一维度增加1,在一个已经找到bug的系统里面j/s, 第二维度不增加
找到了一个旧种类的bug i/n 第一维度不增加,在一个没有找到bug的系统里面 (s-j)/s 第二维度增加,
找到了一个新种类的bug (n-i)/n 第一维度增加,在一个没有找到bug的系统里面 (s-j)/s 第二维度增加,
找到了一个旧种类的bug i/n 第一维度不增加 , 在一个已经找到bug的系统里面 j/s 第二维度不增加
所有状态转移方程是
dp[i][j] = (1-i/n)*j/s*dp[i+1][j] + i/n*(1-j/s)*dp[i][j+1] + (1-i/n)*(1-j/s) * dp[i+1][j+1] + i/n*j/s*dp[i][j] + 1
将红色的部分移到左边化简后得到
dp[i][j] = ((1-i/n)*j/s*dp[i+1][j] + i/n*(1-j/s)*dp[i][j+1] + (1-i/n)*(1-j/s) * dp[i+1][j+1] +1)/(1-i/n*j/s)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
const int INF = << ;
/*
double dp[n][s] 表示已经找到n个种类的bug,在s个子系统中都找到了bug的期望天数 找到了一个新种类的bug (n-i)/n 第一维度增加1,在一个已经找到bug的系统里面j/s, 第二维度不增加
找到了一个旧种类的bug i/n 第一维度不增加,在一个没有找到bug的系统里面 (s-j)/s 第二维度增加,
找到了一个新种类的bug (n-i)/n 第一维度增加,在一个没有找到bug的系统里面 (s-j)/s 第二维度增加,
找到了一个旧种类的bug i/n 第一维度不增加 , 在一个已经找到bug的系统里面 j/s 第二维度不增加 dp[i][j] = (1-i/n)*j/s*dp[i+1][j] + i/n*(1-j/s)*dp[i][j+1] + (1-i/n)*(1-j/s) * dp[i+1][j+1] + i/n*j/s*dp[i][j] dp[i][j] = ((1-i/n)*j/s*dp[i+1][j] + i/n*(1-j/s)*dp[i][j+1] + (1-i/n)*(1-j/s) * dp[i+1][j+1] +1)/(1-i/n*j/s) */
double dp[ + ][ + ];
int main()
{ int n, s;
while (scanf("%d%d", &n, &s) != EOF)
{
memset(dp, , sizeof(dp));
dp[n][s] = ;
for (int i = n; i >= ; --i)
{
for (int j = s; j >= ; --j)
{
if (i == n &&j == s)continue;
dp[i][j] += ( - (double)i / n)*j / s*dp[i + ][j] + (double)i / n*( - (double)j / s)*dp[i][j + ] + ( - (double)i / n)*( - (double)j / s)*dp[i + ][j + ] + ;
dp[i][j] /= ( - (double)i / n*j / s);
}
}
printf("%.4lf\n", dp[][]);
}
return ;
}
hdu4405
给我们n+1个格子, 标号0到n,一个人初始在位置0,然后丢骰子向前走,
然后又给定m个 a b , 表示到了位置a,能够到飞到位置b而不需要丢骰子
问走到>=n的位置 需要丢骰子的期望次数
设dp[i] 为从位置i到>=n的位置需要丢骰子的期望次数
dp[i>=n] = 0
dp[i] = 1/6 * dp[i+1] + 1/6*dp[i+2] + ... + 1/6 * dp[i+6]
如果位置i+k 能够飞行, 那么应该用飞行过后的位置的期望带入去算
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
const int INF = <<;
/*
dp[i>=n] = 0;
dp[i] = dp[i+k] * 1/6
*/
double dp[ + ];
int hs[ + ];
int main()
{
int n, m;
int x, y;
while (scanf("%d%d", &n, &m), n)
{
memset(dp, , sizeof(dp));
memset(hs, , sizeof(hs));
for (int i = ; i < m; ++i)
{
scanf("%d%d", &x, &y);
hs[x] = y;
}
for (int i = n-; i >= ; --i)
{
dp[i] = ;
for (int k = ; k <= ; ++k)
{
if (hs[i + k] != )
{
int t = i + k;
while (hs[t] != )//找到飞行的最终位置, 因为能够多次飞行
{
t = hs[t];
}
dp[i] += dp[t] / ;
}
else
dp[i] += dp[i + k] / ;
}
}
printf("%.4lf\n", dp[]);
}
return ;
}
hdu3853
一个人在迷宫的位置(1,1) 要逃到 迷宫的位置(n,m)
在位置(i,j) 需要2魔力去开启传送阵, 有p1的概率是留在原地, p2的概率往右走,p3的概率往下走
问我们逃到迷宫的位置(n,m)需要的魔力的期望
dp[i][j] = p1 * dp[i][j] + p2*dp[i][j+1] + p3*dp[i+1][j] + 2
dp[i][j] = ( p2*dp[i][j+1] + p3*dp[i+1][j] + 2 ) / (1-p1)
还有一个坑是如果某点停留在原地的概率为1, 这是允许的, 那么肯定所有的点都不会到达这一点,否则答案就会很大,不符合题目所说的
所以应该讲该点的dp[i][j]置为0, 而不应该去计算(万一计算出来很大呢)不然会影响之后的值, 因为虽然走到该点的概率是0, 但是浮点数毕竟有误差。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:1024000000,1024000000")
typedef long long LL;
const int INF = <<;
/*
dp[i][j] = 2 + dp[i][j+1] * p[i][j][1] + dp[i+1][j] * p[i][j][2] + dp[i][j] * p[i][j][0]
dp[i][j] = (2 + dp[i][j+1]*p[i][j][1] + dp[i+1][j] * p[i][j][2])/(1-P[i][j][0]);
*/
const int N = + ;
double p[N][N][];
double dp[N][N];
int main()
{
int n, m;
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = ; i <= n; ++i)
for (int j = ; j <= m; ++j)
for (int k = ; k < ; ++k)
scanf("%lf", &p[i][j][k]);
dp[n][m] = ;
for (int i = n; i >= ; --i)
{
for (int j = m; j >= ; --j)
{
if (i == n &&j == m)
continue;
if (fabs( - p[i][j][]) <= 1e-)//如果该点停留在原地的概率为1, 这是允许的, 那么肯定所有的点都不会到达这一点,否则答案就会很大,不符合题目所说的
{
dp[i][j] = ;
continue;
}
dp[i][j] = (p[i][j][] * dp[i][j + ] + p[i][j][] * dp[i + ][j]) / ( - p[i][j][]) + /(-p[i][j][]);
}
}
printf("%.3lf\n", dp[][]);
}
return ;
}
期望dp专题的更多相关文章
- dp专题训练
****************************************************************************************** 动态规划 专题训练 ...
- 【BZOJ-1419】Red is good 概率期望DP
1419: Red is good Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 660 Solved: 257[Submit][Status][Di ...
- [NOIP2016]换教室 D1 T3 Floyed+期望DP
[NOIP2016]换教室 D1 T3 Description 对于刚上大学的牛牛来说, 他面临的第一个问题是如何根据实际情况中情合适的课程. 在可以选择的课程中,有2n节课程安排在n个时间段上.在第 ...
- HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)
题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...
- 【BZOJ-4008】亚瑟王 概率与期望 + DP
4008: [HNOI2015]亚瑟王 Time Limit: 20 Sec Memory Limit: 512 MBSec Special JudgeSubmit: 832 Solved: 5 ...
- 期望dp BZOJ3450+BZOJ4318
BZOJ3450 概率期望DP f[i]表示到i的期望得分,g[i]表示到i的期望长度. 分三种情况转移: ① s[i]=‘x’:f[i]=f[i-1],g[i]=0 ② s[i]=‘o’:f[i]= ...
- HDU 4405 期望DP
期望DP算是第一题吧...虽然巨水但把思路理理清楚总是好的.. 题意:在一个1×n的格子上掷色子,从0点出发,掷了多少前进几步,同时有些格点直接相连,即若a,b相连,当落到a点时直接飞向b点.求走到n ...
- POJ 2096 【期望DP】
题意: 有n种选择,每种选择对应m种状态.每种选择发生的概率相等,每种选择中对应的每种状态发生的概率相等. 求n种选择和m种状态中每种至少发生一次的期望. 期望DP好别扭啊.要用倒推的方法. dp[i ...
- ZOJ 3822 Domination 期望dp
Domination Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.zju.edu.cn/onlinejudge/showProblem ...
随机推荐
- ym——安卓巴士总结了近百个Android优秀开源项
转载请注明本文出自Cym的博客(http://blog.csdn.net/cym492224103),谢谢支持! 1.Android团队提供的演示样例项目 假设不是从学习Android SDK中提供的 ...
- Maven项目下 java.lang.ClassNotFoundException 常规解决的方法
网上非常多要改动.class .project的比較麻烦有时候还不一定管用.以下的方法适合于项目用已经引用了jar.可是执行时却ClassNotFound,请用例如以下方法试试: 严重: Error ...
- acFileStorage equivalent
searching for a vcl that can enable embed any files within dfm similar to acfilestorage When there a ...
- 开源项目之Android 结束篇
随着公司新的需求以及Android嵌入式的深入,我已经没有多余的时间去扩展学习与Sip或UI不相关的Android开源项目,至此结束! 感想:研究Android已经一年半载了,白天忙公司项目,晚上扩展 ...
- 自己定义android 4.0以上的对话框风格
做个笔记.这里是Dialog的风格,假设是用AlertDialog创建的,不能直接用.在styles.xml的写法: <style name="DialogWindowTitle&qu ...
- cocos2dX 事件之触摸事件和触摸事件集合
今天, 我们来学习cocos2dX里面的触摸事件与触摸事件合集, 如今的手机游戏交互基本上都是通过触摸交互的, 所以大家明确这节的重要性了吧, 本节篇幅比較大, 所以我就不扯闲话了 先来看看经常使用函 ...
- MyBATIS使用CRUD
MyEclipse不提供自己主动生成,这里提供mybatis文件包和开发文档 http://download.csdn.net/detail/u010026901/7489319 自己建立配置文件, ...
- 【菜鸟看框架】——EF怎样自己主动生成实体
引言 在上一篇博客中给大家介绍了一些关于EF框架的基本知识.让大家对实体架构算是有了一个入门的认识,当然知识 这一篇博客是不能非常清楚的理解实体架构的内涵的.我们须要在实践中自己去不断的研究和探索当中 ...
- 千万别用模板给的list.size()巨坑
要用!list.empty()取代i<list.size();否则就不会AC了.
- 表达式树动态拼接lambda
动态拼接lambda表达式树 前言 最近在优化同事写的代码(我们的框架用的是dapperLambda),其中有一个这样很普通的场景——界面上提供了一些查询条件框供用户来进行过滤数据.由于dappe ...