HDU 4487 Maximum Random Walk (概率DP)

来源:互联网 发布:linux重置root密码忘记 编辑:程序博客网 时间:2024/05/22 12:16

Maximum Random Walk

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 505    Accepted Submission(s): 279


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
31 1 0.5 0.52 4 0.5 0.53 10 0.5 0.4
 

Sample Output
1 0.50002 1.18753 1.4965
 

大体题意:告诉你向左走、向右走、不动的概率,和总共的移动步数,让你计算在指定步数内,到达最右端的数学期望。
分析:
比赛没有做出来,还不会概率DP,通过这个题目了解下概率DP。
DP[i][j][k]表示 第i步,在j位置处,所到达最远距离k的概率!
因为第几步计算的话,只需要前一步就够了,因此一维可以改成滚动dp。
然后分三步:
向左走,向右走,不动!

最后计算期望用概率乘以坐标数值即可

#include<cstdio>#include<cstring>#include<algorithm>#define mem(x) memset(x,0,sizeof(x));using namespace std;const int maxn = 200 + 10;double dp[2][maxn][maxn];int main(){int T,cnt;scanf("%d",&T);while(T--){double l,r;int n,u=0,v;scanf("%d%d%lf%lf",&cnt,&n,&l,&r);int len = n;n*=2;//坐标整体向右移动,防止出现负坐标! mem(dp[u]);dp[u][len][len] = 1.0;for (int i = 0; i < len; ++i){//控制步数! v = u ^ 1;//滚动dp; mem(dp[v]);for (int j = 1; j <= n; ++j){for (int k = 1; k <= n; ++k){dp[v][j+1][max(k,j+1)] += dp[u][j][k] * r;//往右走可能会超过k dp[v][j][k] += dp[u][j][k] * (1.0-l-r);//不动! dp[v][j-1][k] += dp[u][j][k] * l;//往左走! }}u = v;}double ans = 0;for (int i = 0; i <= n; ++i)for (int j = len; j <= n; ++j)ans += dp[u][i][j] * (j-len);printf("%d %.4f\n",cnt,ans);}return 0;}


0 0
原创粉丝点击