Codeforce24D Broken robot DP套高斯消元解决DP后效性问题

题意:

在一个 n ∗ m n*m nm的方格上,一个人位于坐标 ( x , y ) (x,y) (x,y)上。在每一个格子等概率的、随机的停在原地,向左移动,向右移动,向下移动。问机器人到最后一行的期望步数多少。

题解:

期望dp。令 d p [ i ] [ j ] dp[i][j] dp[i][j]作为 ( i , j ) (i,j) (i,j)到最后一行的期望步数。期望dp,一般状态的表示都是从后往前,不用 d p [ i ] [ j ] dp[i][j] dp[i][j]作为 ( x , y ) (x,y) (x,y) ( i , j ) (i,j) (i,j)的期望步数:

  • 终点的状态便于表示
  • 对于本题这样多个终点,还需要求 ( x , y ) (x,y) (x,y)到每个终点的概率

推式子还是从前往后推:
j = 1 ,   d p [ i ] [ j ] = 1 3 ( d p [ i ] [ j ] + d p [ i + 1 ] [ j ] + d p [ i ] [ j + 1 ] ) + 1 1 < j < m ,   d p [ i ] [ j ] = 1 4 ( d p [ i ] [ j − 1 ] + d p [ i ] [ j ] + d p [ i + 1 ] [ j ] + d p [ i ] [ j + 1 ] ) + 1 j = m ,   d p [ i ] [ j ] = 1 3 ( d p [ i ] [ j ] + d p [ i + 1 ] [ j ] + d p [ i ] [ j − 1 ] ) + 1 j=1,\ dp[i][j]=\frac{1}{3}(dp[i][j]+dp[i+1][j]+dp[i][j+1])+1\\ 1<j<m, \ dp[i][j]=\frac{1}{4}(dp[i][j-1]+dp[i][j]+dp[i+1][j]+dp[i][j+1])+1\\ j=m,\ dp[i][j]=\frac{1}{3}(dp[i][j]+dp[i+1][j]+dp[i][j-1])+1 j=1, dp[i][j]=31(dp[i][j]+dp[i+1][j]+dp[i][j+1])+11<j<m, dp[i][j]=41(dp[i][j1]+dp[i][j]+dp[i+1][j]+dp[i][j+1])+1j=m, dp[i][j]=31(dp[i][j]+dp[i+1][j]+dp[i][j1])+1
因为可以横向移动,所以一行会有m个等式,m个未知数,形成m个方程。想到线性方程组

显然可以转换线性方程组,以 m = 5 m=5 m=5的线性方程组矩阵 F [ m ] [ m + 1 ] F[m][m+1] F[m][m+1]为例:
[ 2 3 − 1 3 0 0 0 1 3 d p [ i + 1 ] [ 1 ] + 1 − 1 4 3 4 − 1 4 0 0 1 4 d p [ i + 1 ] [ 2 ] + 1 0 − 1 4 3 4 − 1 4 0 1 4 d p [ i + 1 ] [ 3 ] + 1 0 0 − 1 4 3 4 − 1 4 1 4 d p [ i + 1 ] [ 4 ] + 1 0 0 0 2 3 − 1 3 1 3 d p [ i + 1 ] [ 5 ] + 1 ] \begin{bmatrix} \frac{2}{3} & -\frac{1}{3} & 0 & 0&0&\frac{1}{3}dp[i+1][1]+1 \\ -\frac{1}{4}& \frac{3}{4} & -\frac{1}{4}&0&0 &\frac{1}{4}dp[i+1][2]+1\\ 0&-\frac{1}{4}& \frac{3}{4} & -\frac{1}{4}&0 &\frac{1}{4}dp[i+1][3]+1\\ 0&0&-\frac{1}{4}& \frac{3}{4} & -\frac{1}{4}&\frac{1}{4}dp[i+1][4]+1\\ 0&0&0&\frac{2}{3} & -\frac{1}{3}&\frac{1}{3}dp[i+1][5]+1 \end{bmatrix} 3241000314341000414341000414332000413131dp[i+1][1]+141dp[i+1][2]+141dp[i+1][3]+141dp[i+1][4]+131dp[i+1][5]+1
可以观察到,只有对角线和两侧有数,所以不需要高斯消元,暴力模拟即可。

自底向上,使 F [ j − 1 ] [ j ] F[j-1][j] F[j1][j]都变成0;自顶向下,使 F [ j + 1 ] [ j ] F[j+1][j] F[j+1][j]都变成0。

O ( n m ) O(nm) O(nm)完成消元,这样只剩下 F [ j ] [ j ] ≠ 0 F[j][j]\neq 0 F[j][j]=0,求解方程即可。

初始化 ∀ i ∈ [ 1 , m ] , d p [ n ] [ i ] = 0 {\forall}i\in[1,m],dp[n][i]=0 i[1,m],dp[n][i]=0

构造矩阵,求解,得到 d p [ n − 1 ] dp[n-1] dp[n1]

依次,得到 d p [ 1 ] dp[1] dp[1]。输出 d p [ x ] [ y ] dp[x][y] dp[x][y]即可。

特判m=1的情况!

个人认为这是一道很好的DP套高斯消元的题。对于当图上可以横向和向下移动时,是一个很优秀的解法。当DP过程中出现循环的时候,有很好的借鉴意义。

AC代码:

#include <cstdio>
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
#include <cmath>
#include <set>
#include <map>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define lep(i,a,b) for(int i=(a);i>=(b);i--) 
#define pii pair<int,int>
#define pll pair<long long,long long>
#define mp make_pair
#define pb push_back 
#define fir first
#define sec second
#define All(x) x.begin(),x.end() 
#define ms(a,b) memset(a,b,sizeof(a)) 
#define INF 0x3f3f3f3f
#define INFF 0x3f3f3f3f3f3f3f3f
#define multi int T;scanf("%d",&T);while(T--) 
using namespace std;
typedef long long ll;
typedef double db;
const int N=1e3+5;
const int mod=10007;
const db eps=1e-6;
const db pi=acos(-1.0);
int n,m,x,y;
db f[N][N],dp[N][N];
int main(){
    #ifndef ONLINE_JUDGE
    freopen("D:\\work\\data.in","r",stdin);
    #endif  
    cin>>n>>m>>x>>y;
    if(m==1){
        printf("%.10lf",2.0*(n-x));
        return 0;
    }
    lep(i,n-1,1){
        f[1][1]=f[m][m]=2.0/3;
        f[1][2]=f[m][m-1]=-1.0/3;
        rep(j,2,m-1) f[j][j]=3.0/4,f[j][j-1]=f[j][j+1]=-1.0/4;
        f[1][m+1]=dp[i+1][1]/3+1;
        f[m][m+1]=dp[i+1][m]/3+1;
        rep(j,2,m-1) f[j][m+1]=dp[i+1][j]/4+1;
        lep(j,m,2){
            db k=f[j-1][j]/f[j][j];
            f[j-1][j-1]-=k*f[j][j-1];
            f[j-1][j]-=k*f[j][j];
            f[j-1][m+1]-=k*f[j][m+1];
        }
        rep(j,1,m-1){
            db k=f[j+1][j]/f[j][j];
            f[j+1][j]-=k*f[j][j];
            f[j+1][m+1]-=k*f[j][m+1];
        }
        rep(j,1,m) dp[i][j]=f[j][m+1]/f[j][j];
    }
    printf("%.10lf",dp[x][y]);
}

猜你喜欢

转载自blog.csdn.net/Luowaterbi/article/details/110845929