• 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;
    }
    
    
  • 相关阅读:
    ExtJs多级联动菜单的一种实现
    初学jquery之自学笔记(2)
    微软MVP评Silverlight的功能特性和价值
    利用XMLFormView在Web部件页中或者自定义页面中嵌入Infopath表单
    初学jquery之自学笔记(3)
    我想大声告诉你
    HTC G7 金卡 制作
    黑苹果配置
    我的Android 从 2.3开始! 开发环境搭建
    新台式机配置表
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14715746.html
Copyright © 2020-2023  润新知