zoukankan      html  css  js  c++  java
  • HDU-4487 Maximum Random Walk(概率dp)

    题目链接

    题目大意

      随机游走问题的变形,给你每一步向左走和向右走的概率,问第n步走到的最远距离的期望。

    解题思路

      直接求期望不太好做,不过可以先求出概率,设(dp[i][j][k])表示第i步在j位置,最远走到了k位置,那么第i+1步可能是第i步向左走,向右走,原地不动三种情况转移过来的。我们分类讨论一下。
      如果向右走的话,可能下一步走的位置比原来更远,说明j+1>k,我们可以更新(dp[i+1][j+1][j+1] = dp[i][j][k] imes p_r),也可能没有比原来的远,这时候最远的位置仍是k,所以更新(dp[i+1][j+1][k] = dp[i][j][k] imes p_r)
      如果向左走,显然只有一种情况,(dp[i+1][j-1][k] = dp[i][j][k] imes p_l)
      如果原地不动的话,也是一种情况,(dp[i+1][j][k] = dp[i][j][k] imes 1-(p_l+p_r))
      因为题目有内存限制,而且第一维转移的时候只与下一个状态有关系,所以可以用滚动数组省下空间,还有一点需要注意的是,有走到负数的情况,所以对于数组后两维整体+100。

    代码

    #include<bits/stdc++.h>
    #define endl '
    '
    #define x first
    #define y second
    #define clr(arr,a) memset(arr, a, sizeof(arr))
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> P;
    typedef pair<ll, int> Pll;
    const double pi = acos(-1.0);
    const double eps = 1e-8;
    const int MOD = 11380;
    const int INF = 0x3f3f3f3f;
    const int maxn = 2e2+10;
    double dp[2][maxn][maxn];
    const double fx = 100;
    int main(void) {
        int __; cin >> __;
        while(__--) {
            int k, n; double pl, pr; cin >> k >> n >> pl >> pr;
            clr(dp, 0);
            dp[0][100][100] = 1;
            for (int i = 0; i<=n; ++i) {
                for (int j = 100-i; j<=100+i; ++j)
                    for (int k = 100-i; k<=100+i; ++k) {
                        int nxt = (i+1)&1;
                        dp[nxt][j][k] = 0;
                    }
                for (int j = 100-i; j<=100+i; ++j)
                    for (int k = 100-i; k<=100+i; ++k) {
                        if (j>k) continue;
                        int nxt = (i+1)&1;
                        int now = i&1;
                        if (j+1<=k) dp[nxt][j+1][k] += dp[now][j][k]*pr;
                        if (j+1>k) dp[nxt][j+1][j+1] += dp[now][j][k]*pr;
                        if (j) dp[nxt][j-1][k] += dp[now][j][k]*pl;
                        dp[nxt][j][k] += dp[now][j][k]*(1-pl-pr);
                    }
            }
            double sum = 0;
            for (int i = 100-n; i<=100+n; ++i)
                for (int j = 100-n; j<=100+n; ++j) {
                    sum += (j-100)*dp[n&1][i][j];
                }
            printf("%d %.4f
    ", k, sum);
        }
        return 0;
    }
    
    
  • 相关阅读:
    Oracle存储过程
    Oracle触发器
    Oracle伪列
    Oracle索引
    Oracle视图
    Oracle数据库链路
    异常处理之动手动脑
    四则运算自动出题之javaweb版
    继承与多态之动手动脑
    javaweb之添加学生信息
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14715746.html
Copyright © 2011-2022 走看看