CodeForces 24 D.Broken robot(概率DP+高斯消元)

33 篇文章 0 订阅
23 篇文章 0 订阅

Description

给出一个 n×m n × m 的矩阵区域,一个机器人初始在第 x x 行第y列,每一步机器人会等概率的选择停在原地,左移一步,右移一步,下移一步,如果机器人在边界则不会往区域外移动,问机器人到达最后一行的期望步数

Input

第一行两个整数 n,m n , m 表示矩阵行列数,之后输入两个整数 x,y x , y 表示机器人初始位置 (1n,m1000,1xn,1ym) ( 1 ≤ n , m ≤ 1000 , 1 ≤ x ≤ n , 1 ≤ y ≤ m )

Output

输出机器人走到最后一行的期望步数

Sample Input

10 10
10 4

Sample Output

0.0000000000

Solution

m=1 m = 1 时每次 12 1 2 概率不动, 12 1 2 概率下移一步,答案显然为 2(nx) 2 ⋅ ( n − x )

dp[i]][j] d p [ i ] ] [ j ] 表示机器人从第 i i 行第j列出发到达最后一行的期望步数,显然 dp[n][j]=0,1jm d p [ n ] [ j ] = 0 , 1 ≤ j ≤ m

由机器人等概率选择停在原地,左移一步,右移一步,下移一步有转移:

dp[i][1]=1+13dp[i][1]+13dp[i][2]+13dp[i+1][1] d p [ i ] [ 1 ] = 1 + 1 3 d p [ i ] [ 1 ] + 1 3 d p [ i ] [ 2 ] + 1 3 d p [ i + 1 ] [ 1 ]

dp[i][j]=1+14dp[i][j]+14dp[i][j1]+14dp[i][j+1]+14dp[i+1][j],1<j<m d p [ i ] [ j ] = 1 + 1 4 d p [ i ] [ j ] + 1 4 d p [ i ] [ j − 1 ] + 1 4 d p [ i ] [ j + 1 ] + 1 4 d p [ i + 1 ] [ j ] , 1 < j < m

dp[i][m]=1+13dp[i][m]+13dp[i][m1]+13dp[i+1][m] d p [ i ] [ m ] = 1 + 1 3 d p [ i ] [ m ] + 1 3 d p [ i ] [ m − 1 ] + 1 3 d p [ i + 1 ] [ m ]

写成矩阵形式

dp[i][1]12dp[i][2]=32+12dp[i+1][1] d p [ i ] [ 1 ] − 1 2 d p [ i ] [ 2 ] = 3 2 + 1 2 d p [ i + 1 ] [ 1 ]

14dp[i][j1]+34dp[i][j]14dp[i][j+1]=1+14dp[i+1][j],1<j<m − 1 4 d p [ i ] [ j − 1 ] + 3 4 d p [ i ] [ j ] − 1 4 d p [ i ] [ j + 1 ] = 1 + 1 4 d p [ i + 1 ] [ j ] , 1 < j < m

12dp[i][m1]+dp[i][m]=32+12dp[i+1][m] − 1 2 d p [ i ] [ m − 1 ] + d p [ i ] [ m ] = 3 2 + 1 2 d p [ i + 1 ] [ m ]

由于转移矩阵是一个三对角矩阵, O(n) O ( n ) 即可消元,即通过第一行的 dp[i][1]+a[1]dp[i][2]=b[1] d p [ i ] [ 1 ] + a [ 1 ] ⋅ d p [ i ] [ 2 ] = b [ 1 ] 和第二行消去 dp[i][1] d p [ i ] [ 1 ] 得到 dp[i][2]+a[2]dp[i][3]=b[2] d p [ i ] [ 2 ] + a [ 2 ] ⋅ d p [ i ] [ 3 ] = b [ 2 ] ,以此类推求出 dp[i][j]+a[j]dp[i][j+1]=b[j],1j<m d p [ i ] [ j ] + a [ j ] ⋅ d p [ i ] [ j + 1 ] = b [ j ] , 1 ≤ j < m ,用 dp[i][m1]+a[m1]dp[i][m]=b[m1] d p [ i ] [ m − 1 ] + a [ m − 1 ] ⋅ d p [ i ] [ m ] = b [ m − 1 ] 以及最后一个等式求出 dp[i][m] d p [ i ] [ m ] ,然后从后往前通过 dp[i][j]=b[j]a[j]dp[i][j+1] d p [ i ] [ j ] = b [ j ] − a [ j ] ⋅ d p [ i ] [ j + 1 ] 求出所有的 dp[i][j] d p [ i ] [ j ] 即可,时间复杂度 O(n2) O ( n 2 )

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=1005;
int n,m,x,y;
double a[maxn],b[maxn],dp[maxn][maxn];
int main()
{
    scanf("%d%d%d%d",&n,&m,&x,&y);
    if(m==1)printf("%.5f\n",2.0*(n-x));
    else
    {
        for(int j=1;j<=m;j++)dp[n][j]=0;
        for(int i=n-1;i>=x;i--)
        {
            a[1]=-0.5;b[1]=1.5+0.5*dp[i+1][1];
            for(int j=2;j<m;j++)
            {
                b[j]=1.0+0.25*dp[i+1][j]+0.25*b[j-1];
                a[j]=-0.25;
                double temp=0.75+0.25*a[j-1];
                a[j]/=temp;b[j]/=temp;
            }
            dp[i][m]=(3.0+dp[i+1][m]+b[m-1])/(2.0+a[m-1]);
            for(int j=m-1;j>=1;j--)dp[i][j]=b[j]-a[j]*dp[i][j+1];
        }
        printf("%.5f\n",dp[x][y]);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值