Description
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?
Input
Output
Please calculate the expected number of steps required to reach the KEY room, there are 2 digits after the decimal point.
Sample Input
Sample Output
去年省赛的题。。。
下楼梯,一开始在最上面,只能往左下,右下,左(如果有)走,知道每步的概率,问到达左下角那个点的期望。
用记忆化搜索写了个,搜索所有可能路径,加上所有路径的步数*概率。样例过了交上去TLE,试了几个发现层数多的时候概率出来都是0.00000。。。
然后我又设dp[i][j]为从起点到达第i层第j个的期望,下一步的期望就加上所有上一步的p*(dp[i][j]+1),结果又不对。。因为到达某个地方的期望为∑p(i)*step(i),也就是对所有到达这个地方的路径的概率*步数求和,如果到达这个地方的下一地方概率为P,那么到下一个地方期望为∑P*p(i)*(step(i)+1),也就是P*[(dp[i][j]+1)+∑p(i)],所以只有在到上一步概率和为1的情况下才能像我刚那么做,但是从上往下到每一步的概率和不一定为1。
再网上搜了一些资料,貌似期望DP很多都是从后往前推。那么,设dp[i][j]为第i层第j个到左下角的期望,有木有发现把我刚才那个p*(dp[i][j]+1)从后往前推就对了。。因为如果把整个过程倒着想,从某个点能到达的那些点反过来到达这个点,概率和就为1(正着到达某个点的概率和不一定为1,但从每个点出发的路径概率和一定为1),这样一路上所有点到达左下角路径概率和都为1(因为就是从左下角出发的)。
设dp[i][j]为第i层第j个到左下角的期望,再一层一层倒过来递推就行了,注意全都要到过来,以前是从右往左,现在要变成从左往右。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cstdlib>
#define INF 0x3f3f3f3f
#define MAXN 55
#define MAXM 15
#define MAXNODE 4*MAXN
#define pii pair<int,int>
using namespace std;
int N;
double dp[MAXN][MAXN];
int main(){
while(scanf("%d",&N),N){
double a,b,c,d,e;
scanf("%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e);
memset(dp,0,sizeof(dp));
dp[N][1]=0;
for(int i=2;i<=N;i++) dp[N][i]=dp[N][i-1]+1;
for(int i=N-1;i>=1;i--)
for(int j=1;j<=i;j++){
if(j==1) dp[i][j]+=(dp[i+1][j]+1)*a+(dp[i+1][j+1]+1)*b;
else dp[i][j]+=(dp[i+1][j]+1)*c+(dp[i+1][j+1]+1)*d+dp[i][j]+(dp[i][j-1]+1)*e;
}
printf("%.2lf\n",dp[1][1]);
}
return 0;
}