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;
    }
    
    
  • 相关阅读:
    打造基于CentOS7的xfce最简工作环境
    Linux下C程序的编辑,编译和运行以及调试
    修正 XE6 TListView 上方 SearchBok 右边的清除钮显示
    TabControl 显示彩色的图示 (XE6 Firemonkey)
    TSwitch 中文简繁显示支持(XE6 Android)
    改变 TMemo 的背景颜色 (Firemonkey)
    修正 XE5 Android 键盘三个问题
    Delphi 收藏
    展示 Popup 的使用方法
    ListView 下拉更新 (支持 Android)
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/14715746.html
Copyright © 2011-2022 走看看