upc 2225 The number of steps 期望DP

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

There are no more than 70 test cases. 
In each case , first Input a positive integer n(0<n<45), which means the layer of the maze, then Input five real number a, b, c, d, e. (0<=a,b,c,d,e<=1, a+b=1, c+d+e=1). 
The input is terminated with 0. This test case is not to be processed.

Output

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

Sample Input

30.3 0.70.1 0.3 0.60

Sample Output

3.41

 

  去年省赛的题。。。

  下楼梯,一开始在最上面,只能往左下,右下,左(如果有)走,知道每步的概率,问到达左下角那个点的期望。

  用记忆化搜索写了个,搜索所有可能路径,加上所有路径的步数*概率。样例过了交上去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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值