zoukankan      html  css  js  c++  java
  • hdu--4487--dp

    dp是最有意思的。。 因为它永远没有固定的套路。。

    最无聊的就是那些模板题了。。

    这题 我被坑了。。  题意读错了。。   这边问的是A more interesting question is what is the expected rightmost position you will attain during the walk.

    就是说 我们在每一次的走路过程中 所能达到的最右边的位置 我起初看成 走完n步以后 可以达到的最右边的位置= =

    这边 是个很明显的 线性期望dp

    一共就2个状态转移  对于dp[x,y,z] 走到了第x步 当前的位置是y 此时在这x步的过程中到底的最右边的距离是z

    那么y与z一共就有3个大小关系了

    y<z 

    dp[x&1][y][z] = dp[(x-1)&1][y+1][z] * L + dp[(x-1)&1][y][z] * M + dp[(x-1)&1][y-1][z] * R;

    首先你要明确 dp[x,y,z]我是由dp[x-1,u,v]这个状态转移过来的 那么因为最多走一步 所以那就保证了即使我在u处向前走了一步 也不能超过v 最多可能等于v

    y==z

    dp[x&1][y][z] = dp[(x-1)&1][y-1][z-1] * R + dp[(x-1)&1][y][z] * M + dp[(x-1)&1][y-1][z] * R;

    这时候就是说可能 我是第一次到达了z这个位置 或者我上一步就停在了z这个位置 或者是 我上上一步到达了z 但是上一步往左走了 这一步又往右走了 就还是最远距离是z

    y<z

    因为我现在都已经处在了 y 这个位置 那么离右边的最远距离z肯定是起码等于y啊<左边就拿原点处理>

    至于 这个滚动数组 优化与否 没什么关系 数据很小 才100  

     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 int n;
     7 double L , R , M;
     8 const int size = 105;
     9 double dp[2][size*2][size*2];//dp[i,j,k]走到第i步的时候 走到了j这个位置 此时到达最右边的距离是k
    10 
    11 void init( )
    12 {
    13     memset( dp , 0 , sizeof(dp) );
    14     dp[0][size][size] = 1;
    15 }
    16 
    17 void solve( )
    18 {
    19     for( int i = 1 ; i<=n ; i++ )
    20     {
    21         for( int j = size-i ; i<=size+i ; j++ )
    22         {
    23             for( int k = max(j,size) ; k<=size+i ; k++ )
    24             {
    25                 if( j==k )//第一次走到j这个位置     原地走    走到K之后 往回走了 现在再重新往前走
    26                 {
    27                     dp[i&1][j][k] = dp[(i-1)&1][j-1][k-1] * R + dp[(i-1)&1][j][k] * M + dp[(i-1)&1][j-1][k] * R;
    28                 }
    29                 else// k > j的情况
    30                 {
    31                     dp[i&1][j][k] = dp[(i-1)&1][j+1][k] * L + dp[(i-1)&1][j][k] * M + dp[(i-1)&1][j-1][k] * R;
    32                 }
    33             }
    34         }
    35     }
    36 }
    37 
    38 int main()
    39 {
    40     int t , m;
    41     double ans;
    42     scanf( "%d",&t );
    43     while( t-- )
    44     {
    45         init( );
    46         scanf( "%d %d %lf %lf",&m,&n,&L,&R );
    47         M = 1 - L - R;
    48         solve( );    
    49         ans = 0;
    50         for( int j = size - n ; j<=size+n ; j++ )
    51         {
    52             for( int k = size ; k<=size+n ; k++ )
    53             {
    54                 ans += dp[n&1][j][k] * (k-size);
    55             }
    56         }
    57         printf( "%.4lf
    ",ans );
    58     }
    59     return 0;
    60 }
    View Code
  • 相关阅读:
    不要在linux上启用net.ipv4.tcp_tw_recycle参数
    Linux如何用查看域名解析
    APP请求超时问题-ios超时-android超时
    写给正在入坑linux系统的伙伴
    产品经理必看书单
    Mysql遍历大表(Mysql大量数据读取内存溢出的解决方法)
    产品上线标准
    测试时间的评估【搬运】
    如何估算测试工作量(一)常规的估算测试工作量的方法
    测试工作量的评估方法
  • 原文地址:https://www.cnblogs.com/radical/p/4156346.html
Copyright © 2011-2022 走看看