HDU 4487 Maximum Random Walk (概率DP)

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
   
   
   
   
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
 

大体题意:告诉你向左走、向右走、不动的概率,和总共的移动步数,让你计算在指定步数内,到达最右端的数学期望。
分析:
比赛没有做出来,还不会概率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;
}


你可能感兴趣的:(dp,动态规划,C语言)