问题 D: Maximum Random Walk

时间限制: 10 Sec 内存限制: 128 MB

提交 状态 题面

题目描述

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.

输入

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 ≤ 1000). 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.

输出

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.

样例输入

4

1 1 0.5 0.5

2 4 0.5 0.5

3 10 0.5 0.4

4 1000 0.5 0.4

样例输出

1 0.5000

2 1.1875

3 1.4965

4 3.9995

O(n^3)概率dp,被卡掉了,但其他oj应该能过去,自家oj应该是加了一组15*1000的数据

//O(n^3)
#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
#include <stack>
#include <set>
using namespace std;
typedef  long long ll;
const int maxn=1010;
int n,s;
double l,r,inp;
double dp[3][maxn<<1][maxn<<1];
int main()
{
    int _;
    scanf("%d",&_);
    while(_--){
        scanf("%d%d%lf%lf",&n,&s,&l,&r);
        inp=1.0-l-r;
        memset(dp,0,sizeof(dp));
        dp[0][1000][1000]=1;
        int f=0;
        for(int i=1;i<=s;i++,f^=1)
            for(int j=1000-i;j<=1000+i;j++){
                for(int k=j>1000?j:1000;k<=1000+i;++k){
                    if(j==k)
                        dp[f^1][j][k]=dp[f][j][k]*inp+dp[f][j-1][k-1]*r+dp[f][j-1][k]*r;
                    else
                        dp[f^1][j][k]=dp[f][j][k]*inp+dp[f][j-1][k]*r+dp[f][j+1][k]*l;
                }
            }
        double ans=0;
        for(int i=1000-s;i<=1000+s;++i)
            for(int j=1000;j<=1000+s;++j)
                ans+=dp[f][i][j]*(j-1000);
        printf("%d %.4f\n",n,ans);
    }
    return 0;
}
//O(n^2)
#pragma GCC optimize(3,"Ofast","inline")
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <vector>
#include <map>
#include <cmath>
#include <stack>
#include <set>
using namespace std;
typedef  long long ll;
const int maxn=1010;
double l,r,inp;
double dp[maxn][maxn];
double solve(int n){
    dp[0][0]=1;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=i;j++){
            dp[i][j]=0;
            if(j) dp[i][j]+=dp[i-1][j-1]*r;
            if(j<i) dp[i][j]+=dp[i-1][j]*inp;
            else dp[i][j]+=inp;
            if(j<i-1) dp[i][j]+=dp[i-1][j+1]*l;
            else dp[i][j]+=l;
        }
    }
    double ans=0;
    for(int i=1;i<=n;i++) ans+=(dp[n][i]-dp[n][i-1])*i;
    return ans;
}
int main()
{
    int _;
    scanf("%d",&_);
    while(_--){
        int n,num;
        scanf("%d %d %lf %lf",&num,&n,&l,&r);
        inp=1-l-r;
        printf("%d %.4lf\n",num,solve(n) );
    }
    return 0;
}

留下评论

通过 WordPress.com 设计一个这样的站点
从这里开始