Poj 2096 (dp求期望) 概率dp
来源:互联网 发布:excel下拉菜单关联数据 编辑:程序博客网 时间:2024/04/30 20:16
Poj 2096 (dp求期望)
分类: 动态规划2011-09-14 15:25 1581人阅读 评论(10) 收藏 举报
这题虽然代码很简单,但这是我第一题用dp求数学期望的题目,也算是入个门吧...
- /**
- dp求期望的题。
- 题意:一个软件有s个子系统,会产生n种bug。
- 某人一天发现一个bug,这个bug属于某种bug,发生在某个子系统中。
- 求找到所有的n种bug,且每个子系统都找到bug,这样所要的天数的期望。
- 需要注意的是:bug的数量是无穷大的,所以发现一个bug,出现在某个子系统的概率是1/s,
- 属于某种类型的概率是1/n。
- 解法:
- dp[i][j]表示已经找到i种bug,并存在于j个子系统中,要达到目标状态的天数的期望。
- 显然,dp[n][s]=0,因为已经达到目标了。而dp[0][0]就是我们要求的答案。
- dp[i][j]状态可以转化成以下四种:
- dp[i][j] 发现一个bug属于已经找到的i种bug和j个子系统中
- dp[i+1][j] 发现一个bug属于新的一种bug,但属于已经找到的j种子系统
- dp[i][j+1] 发现一个bug属于已经找到的i种bug,但属于新的子系统
- dp[i+1][j+1]发现一个bug属于新的一种bug和新的一个子系统
- 以上四种的概率分别为:
- p1 = i*j / (n*s)
- p2 = (n-i)*j / (n*s)
- p3 = i*(s-j) / (n*s)
- p4 = (n-i)*(s-j) / (n*s)
- 又有:期望可以分解成多个子期望的加权和,权为子期望发生的概率,即 E(aA+bB+...) = aE(A) + bE(B) +...
- 所以:
- dp[i,j] = p1*dp[i,j] + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] + 1;
- 整理得:
- dp[i,j] = ( 1 + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] )/( 1-p1 )
- = ( n*s + (n-i)*j*dp[i+1,j] + i*(s-j)*dp[i,j+1] + (n-i)*(s-j)*dp[i+1,j+1] )/( n*s - i*j )
- **/
- #include <cstdio>
- #include <iostream>
- using namespace std;
- double dp[1005][1005];
- int main()
- {
- int n, s, ns;
- cin >> n >> s;
- ns = n*s;
- dp[n][s] = 0.0;
- for (int i = n; i >= 0; i--)
- for (int j = s; j >= 0; j--)
- {
- if ( i == n && j == s ) continue;
- dp[i][j] = ( ns + (n-i)*j*dp[i+1][j] + i*(s-j)*dp[i][j+1] + (n-i)*(s-j)*dp[i+1][j+1] )/( ns - i*j );
- }
- printf("%.4lf\n", dp[0][0]);
- return 0;
- }
Zoj 3329 (dp求期望)
分类: 动态规划2011-09-14 20:23 1376人阅读 评论(6) 收藏 举报
游戏c
第二个dp求数学期望的题,如果看不懂,请看我的第一个dp求期望的题(Poj 2096)
令 f[i][j] 表示已经找到了 i 种 bug,且 j 个子系统至少包含一个 bug,距离完成目标需要的时间的期望。
目标状态是 f[0][0]
再过一天找到一个 bug 可能是如下的情况:
1. 这个 bug 的种类是 已经找到的 并且 出现在 已经找到 bug 的子系统中
2. 这个 bug 的种类是 已经找到的 并且 出现在 没有找到 bug 的子系统中
3. 这个 bug 的种类是 没有找到的 并且 出现在 已经找到 bug 的子系统中
4. 这个 bug 的种类是 没有找到的 并且 出现在 没有找到 bug 的子系统中
- /**
- dp求期望的题。
- 题意:
- 有三个均匀的骰子,分别有k1,k2,k3个面,初始分数是0,
- 当掷三个骰子的点数分别为a,b,c的时候,分数清零,否则分数加上三个骰子的点数和,
- 当分数>n的时候结束。求需要掷骰子的次数的期望。
- 题解:
- 设 E[i]表示现在分数为i,到结束游戏所要掷骰子的次数的期望值。
- 显然 E[>n] = 0; E[0]即为所求答案;
- E[i] = ∑Pk*E[i+k] + P0*E[0] + 1; (Pk表示点数和为k的概率,P0表示分数清零的概率)
- 由上式发现每个 E[i]都包含 E[0],而 E[0]又是我们要求的,是个定值。
- 设 E[i] = a[i]*E[0] + b[i];
- 将其带入上面的式子:
- E[i] = ( ∑Pk*a[i+k] + P0 )*E[0] + ∑Pk*b[i+k] + 1;
- 显然,
- a[i] = ∑Pk*a[i+k] + P0;
- b[i] = ∑Pk*b[i+k] + 1;
- 当 i > n 时:
- E[i] = a[i]*E[0] + b[i] = 0;
- 所以 a[i>n] = b[i>n] = 0;
- 可依次算出 a[n],b[n]; a[n-1],b[n-1] ... a[0],b[0];
- 则 E[0] = b[0]/(1 - a[0]);
- **/
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- using namespace std;
- int main()
- {
- int nc, n, ks, k1, k2, k3, a, b, c;
- double p0, p[20];
- cin >> nc;
- while ( nc-- )
- {
- cin >> n >> k1 >> k2 >> k3 >> a >> b >> c;
- ks = k1 + k2 + k3;
- p0 = 1.0 / (k1*k2*k3);
- memset(p, 0, sizeof(p));
- for (int i = 1; i <= k1; i++)
- for (int j = 1; j <= k2; j++)
- for (int k = 1; k <= k3; k++)
- {
- if ( i != a || j != b || k != c )
- p[i+j+k] += p0;
- }
- double a[520] = {0}, b[520] = {0};
- for (int i = n; i >= 0; i--)
- {
- for (int k = 3; k <= ks; k++)
- {
- a[i] += a[i+k]*p[k];
- b[i] += b[i+k]*p[k];
- }
- a[i] += p0;
- b[i] += 1;
- }
- printf("%.15lf\n", b[0]/(1 - a[0]) );
- }
- return 0;
- }
Poj 2096 (dp求期望)
分类: 动态规划2011-09-14 15:25 1580人阅读 评论(10) 收藏 举报
这题虽然代码很简单,但这是我第一题用dp求数学期望的题目,也算是入个门吧...
- /**
- dp求期望的题。
- 题意:一个软件有s个子系统,会产生n种bug。
- 某人一天发现一个bug,这个bug属于某种bug,发生在某个子系统中。
- 求找到所有的n种bug,且每个子系统都找到bug,这样所要的天数的期望。
- 需要注意的是:bug的数量是无穷大的,所以发现一个bug,出现在某个子系统的概率是1/s,
- 属于某种类型的概率是1/n。
- 解法:
- dp[i][j]表示已经找到i种bug,并存在于j个子系统中,要达到目标状态的天数的期望。
- 显然,dp[n][s]=0,因为已经达到目标了。而dp[0][0]就是我们要求的答案。
- dp[i][j]状态可以转化成以下四种:
- dp[i][j] 发现一个bug属于已经找到的i种bug和j个子系统中
- dp[i+1][j] 发现一个bug属于新的一种bug,但属于已经找到的j种子系统
- dp[i][j+1] 发现一个bug属于已经找到的i种bug,但属于新的子系统
- dp[i+1][j+1]发现一个bug属于新的一种bug和新的一个子系统
- 以上四种的概率分别为:
- p1 = i*j / (n*s)
- p2 = (n-i)*j / (n*s)
- p3 = i*(s-j) / (n*s)
- p4 = (n-i)*(s-j) / (n*s)
- 又有:期望可以分解成多个子期望的加权和,权为子期望发生的概率,即 E(aA+bB+...) = aE(A) + bE(B) +...
- 所以:
- dp[i,j] = p1*dp[i,j] + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] + 1;
- 整理得:
- dp[i,j] = ( 1 + p2*dp[i+1,j] + p3*dp[i,j+1] + p4*dp[i+1,j+1] )/( 1-p1 )
- = ( n*s + (n-i)*j*dp[i+1,j] + i*(s-j)*dp[i,j+1] + (n-i)*(s-j)*dp[i+1,j+1] )/( n*s - i*j )
- **/
- #include <cstdio>
- #include <iostream>
- using namespace std;
- double dp[1005][1005];
- int main()
- {
- int n, s, ns;
- cin >> n >> s;
- ns = n*s;
- dp[n][s] = 0.0;
- for (int i = n; i >= 0; i--)
- for (int j = s; j >= 0; j--)
- {
- if ( i == n && j == s ) continue;
- dp[i][j] = ( ns + (n-i)*j*dp[i+1][j] + i*(s-j)*dp[i][j+1] + (n-i)*(s-j)*dp[i+1][j+1] )/( ns - i*j );
- }
- printf("%.4lf\n", dp[0][0]);
- return 0;
- }
- Poj 2096 (dp求期望) 概率dp
- poj 2096(概率dp求期望)
- 概率dp 求期望
- POJ 2096 Collecting Bugs(概率DP求期望)
- poj 2096 Collecting Bugs 概率dp求期望
- POJ 2096 - Collecting Bugs(概率DP 求期望)
- poj 2096 Collecting Bugs 概率DP求期望(简单)
- POJ 2096 Collecting Bugs 概率dp 求期望 入门
- POJ 2096 Collecting Bugs(概率DP求期望)
- Poj 2096 Collecting Bugs (概率DP求期望)
- POJ 2096 Collecting Bugs(概率DP,求期望)
- poj 2096 Collecting Bugs【概率dp 逆向求期望】
- Poj 2096 (dp求期望)
- poj 2096 dp 求 期望
- Collecting Bugs+POJ 2096+概率期望dp
- POJ 2096 Collecting Bugs 概率DP(期望)
- POJ 2096Collecting Bugs(概率期望dp)
- HDU4405(概率DP求期望)
- 装饰者模式
- 怎样进行Xss攻击
- Mount挂载命令使用方法
- 使Maven 2在package、install等阶段跳过运行Test的配置
- strstr和memcmp函数的实现
- Poj 2096 (dp求期望) 概率dp
- 机器学习实战笔记:决策树
- 解决eclipse中egit中的cannot open git-upload-pack问题
- 简单破解 Sencha Architect 2.2
- clock_gettime测代码运行时间
- 如何将Jason中的NSString类型转化为NSArray类型
- Linux Mount远程目录
- Intent在Android中的几种用法 .
- MHA masterha_master_switch 命令的用法三种介绍