Maximum Random Walk
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 224 Accepted Submission(s): 124
Problem Description
Consider the classic random walk: at each step, you have a 1/2 chance of taking a step to the left and a 1/2 chance of taking a step to the right. Your expected position after a period of time is zero; that is, the average over many such random walks is that you end up where you started. A more interesting question is what is the expected rightmost position you will attain during the walk.
Input
The first line of input contains a single integer P, (1 <= P <= 15), which is the number of data sets that follow. Each data set should be processed identically and independently.
Each data set consists of a single line of input consisting of four space-separated values. The first value is an integer K, which is the data set number. Next is an integer n, which is the number of steps to take (1 <= n <= 100). The final two are double precision floating-point values L and R
which are the probabilities of taking a step left or right respectively at each step (0 <= L <= 1, 0 <= R <= 1, 0 <= L+R <= 1). Note: the probably of not taking a step would be 1-L-R.
Output
For each data set there is a single line of output. It contains the data set number, followed by a single space which is then followed by the expected (average) rightmost position you will obtain during the walk, as a double precision floating point value to four decimal places.
Sample Input
3
1 1 0.5 0.5
2 4 0.5 0.5
3 10 0.5 0.4
Sample Output
1 0.5000
2 1.1875
3 1.4965
Source
Greater New York 2012
Recommend
liuyiding
题意:
给你一人走的步数n。和每一步往左走的概率l.往右走的概率r。问你走完n步后途中能到的最右边的位置的期望。
开始没读懂题。其实是一道很水的概率dp。
用dp[v][i][j]表示当前前位置在i。途中走到的最右边的位置为j。那么状态转移方程为:
往右走:
1.如果i+1>j。dp[v^1][i+1][i+1]+=dp[v][i][j]*r。
2.如果i+1<=j。dp[v^1][i+1][j]+=dp[v][i][j]*r。
往左走:
dp[v^1][i-1][j]+=dp[v][i][j]*l。
不走:
dp[v^1][i][j]+=dp[v][i][j]*(1-l-r)。
但需要注意的是。i可能为负数所以把起点往右移动100个位置。
#include <iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
double dp[2][201][110],ans,stop;//一维用于滚动。二维记录当前位置。三维记录走过的最大位置
int main()
{
int p,cas,pace,i,j,v,limit,t;
double l,r;
scanf("%d",&p);
while(p--)
{
scanf("%d%d%lf%lf",&cas,&pace,&l,&r);
v=0;
limit=pace+100;
memset(dp[v],0,sizeof dp[v]);
dp[v][100][0]=1;
t=pace;
stop=1.0-l-r;
while(t--)
{
memset(dp[v^1],0,sizeof dp[v^1]);
for(i=0; i<=limit; i++)
{
for(j=0; j<=pace;j++)
{
if(dp[v][i][j]>0)
{
if(i+1-100>j)
dp[v^1][i+1][i+1-100]+=dp[v][i][j]*r;
else
dp[v^1][i+1][j]+=dp[v][i][j]*r;
dp[v^1][i-1][j]+=dp[v][i][j]*l;
dp[v^1][i][j]+=dp[v][i][j]*stop;
}
}
}
v^=1;
}
ans=0;
for(i=0;i<=limit;i++)
for(j=0;j<=pace;j++)
if(dp[v][i][j]>0)
ans+=j*dp[v][i][j];
printf("%d %.4lf\n",cas,ans);
}
return 0;
}