sdutoj 2623 The number of steps

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2623

The number of steps

Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^

题目描述

Mary stands in a strange maze, the maze looks like a triangle(the first layer have one room,the second layer have two rooms,the third layer have three rooms …). Now she stands at the top point(the first layer), and the KEY of this maze is in the lowest layer’s leftmost room. Known that each room can only access to its left room and lower left and lower right rooms .If a room doesn’t have its left room, the probability of going to the lower left room and lower right room are a and b (a + b = 1 ). If a room only has it’s left room, the probability of going to the room is 1. If a room has its lower left, lower right rooms and its left room, the probability of going to each room are c, d, e (c + d + e = 1). Now , Mary wants to know how many steps she needs to reach the KEY. Dear friend, can you tell Mary the expected number of steps required to reach the KEY?

 

输入

There are no more than 70 test cases.
 
In each case , first Input a positive integer n(0<n<45),
The input is terminated with 0. This test case is not to be processed.

输出

Please calculate the expected number of steps required to reach the KEY room, there are 2 digits after the decimal point.

示例输入

3
0.3 0.7
0.1 0.3 0.6
0

示例输出

3.41

提示

 

来源

2013年山东省第四届ACM大学生程序设计竞赛

示例程序

分析:

第一行有一个位置,第二行两个,第三行三个......第n行n个。此时你在最左上角的位置,如果你左面没有位置,只能往左下和右下走,概率(a,b)。否则可以往左,左下和右下三个方向走,,概率(c,d,e)。让你求到达最左下角的期望。

先科普一下数学期望吧:

首先,来看下期望有啥基本的公式。对离散型随机变量x,其概率为p,有

sdutoj 2623 The number of steps

对随机变量A、B,有 sdutoj 2623 The number of steps

第二个式子表明了期望有线性的性质,简单理解就是期望之间可根据关系,简单运算(不严谨的理解)。 这就为我们解决一个期望问题,不断转化为解决另外的期望问题,最终转化到一个已知的期望上。

举一个求期望最简单的例子,见下图:

sdutoj 2623 The number of steps

假设有个人在 1号节点处,每一分钟他会缘着边随机走到一个节点或者在原地停留,问他走到4号节点需要平均几分钟?

这是个简单的期望问题,我们用Ei(i=1,2,3,4) 表示从i号节点走到4号节点的数学期望值。根据题意对1号节点有

      E1=(1/3)*E1+(1/3)*E2+(1/3)*E3+1 ①

表示 他下一分钟可以走到2或者3或在原地1,每个可能概率是1/3 ,注意是下一分钟,故要加上1.

同理我们对节点2,3同样可以列出:

      E2=(1/3)*E1+(1/3)*E2+(1/3)*E4+1 ②

      E3=(1/3)*E1+(1/3)*E3+(1/3)*E4+1 ③

那E4等于多少呢? 很明显

      E4=0 ④

因为他就是要到点4

这样上面1234式其实就是组成了一组方程组,解方程组就可得出E1!!,用高斯消元,复杂度是O(n^3)

从上述例子,我们可总结出如何解决期望类问题,根据题意,表示出各个状态的期望(上例的Ei,1234),根据概率公式,列出期望之间的方程,解方程即可。

AC代码:

 #include<stdio.h>
#include<string.h>
double dp[][];
int main()
{
int t;
while(scanf("%d",&t),t)
{
int i,j;
double a,b,c,d,e;
scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
memset(dp,,sizeof(dp));
dp[t][]=;
for(i=;i<=t-;i++)
{
dp[t][i+]+=(dp[t][i]+);
}
for(i=t-;i>=;i--)
{
dp[i][]+=a*(dp[i+][]+)+b*(dp[i+][]+);
for(j=;j<=i;j++)
dp[i][j]+=c*(dp[i+][j]+)+d*(dp[i+][j+]+)+e*(dp[i][j-]+);
}
printf("%.2lf\n",dp[][]);
}
return ;
}

官方标程:

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
#define MAXN 1000
#define eps 1e-8
double Atex[MAXN][MAXN];
double a[], b[];
int all;
inline int dcmp(double d) {
return d < -eps ? - : d > eps;
} void gauss(int n, int m)
{
int r,c,i,j;
for(r=c=; r<n&&c<m; r++,c++)
{
for(i=r;i<n;i++)
if(dcmp(Atex[i][c])) break;
if(i==n)//{r--;continue;}
return;
if(i!=r) for(j=c;j<=m;j++) swap(Atex[i][j],Atex[r][j]);
for(i=r+;i<n;i++)
if(Atex[i][c]!=)
{
double temp=Atex[i][c]/Atex[r][c];
for(j=c;j<=m;j++)
Atex[i][j]-=Atex[r][j]*temp;
}
}
for(i=n-;i>=;i--)
{
Atex[i][m]/=Atex[i][i];
Atex[i][i]=;
for(j=i-;j>=;j--) Atex[j][m]-=Atex[i][m]*Atex[j][i];
}
return;
} void makemap(int n) {
memset(Atex, , sizeof(Atex));
all = (+n)*n/;
for (int i = ; i < all; i ++) {
Atex[i][i] = ;
Atex[i][all] = ;
}
int t = , tt;
for (int i = ; i < n-; i ++) {
tt = t + i+;
Atex[t][tt] = -*a[];
Atex[t][tt+] = -*a[];
for (int j = t+; j < tt; j ++) {
Atex[j][j+i+] = -*b[];
Atex[j][j+i+] = -*b[];
Atex[j][j-] = -*b[];
}
t = tt;
}
Atex[t][all] = ;
for (int i = t+; i < all; i ++) {
Atex[i][i-] = -;
}
} int main()
{
int n;
while(scanf("%d", &n) != EOF) {
if(n == ) break;
for (int i = ; i < ; i ++) {
scanf("%lf", &a[i]);
}
for (int i = ; i < ; i ++) {
scanf("%lf", &b[i]);
}
makemap(n);
gauss(all, all);
printf("%.2f\n", Atex[][all]);
}
return ;
}
上一篇:zoj 1081 (改进的弧长算法)(转)


下一篇:改进的SMS4算法的差分故障与暴力联合攻击