• CF24D Broken robot


    不想打式子了,就抄别人的式子吧(毫无版权意识...)

    首先可以列出dp方程,然后可以发现他有后效性

     

    可以把各状态看成未知量,状态转移看做方程,由于全为一次方程,所以可以用高斯消元求解

    而本题使用倒推更为方便,可以将行作为阶段,倒序递推

    如果直接高斯消元复杂度是$O(n^4)$

    然后注意到每个方程只有极少的非零系数,且排列有规律

    如:

    所以我们可以快速消元

    $code:$

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1007;
    int n,m,x,y;
    double f[N],a[N][N],b[N];
    void build(){
        a[1][1]=2.0/3.0;
        a[m][m]=2.0/3.0;
        a[1][2]=-1.0/3.0;
        a[m][m-1]=-1.0/3.0;
        for(int i=2;i<=m-1;i++){
            a[i][i]=3.0/4.0;
            a[i][i-1]=-1.0/4.0;
            a[i][i+1]=-1.0/4.0;
        }
    }
    void gauss(){
        for(int i=1;i<=m;i++){
            double rate=a[i+1][i]/a[i][i];
            a[i+1][i]-=rate*a[i][i];
            a[i+1][i+1]-=rate*a[i][i+1];
            b[i+1]-=rate*b[i];
        }
        f[m]=b[m]/a[m][m];  
        for(int i=m-1;i>0;i--){
            f[i]=(b[i]-f[i+1]*a[i][i+1])/a[i][i];
        }
    }
    int main(){
        cin>>n>>m>>x>>y;
        if(m==1){
            printf("%.8lf
    ",(double)2.0*(n-x));
            return 0;
        }
        for(int i=n-1;i>=x;i--){
            b[1]=f[1]/3.0+1.0;
            b[m]=f[m]/3.0+1.0;
            for(int j=2;j<m;j++){
                b[j]=f[j]/4+1.0;
            }
            build();
            gauss();
        }
        printf("%.8lf
    ",f[y]);
        return 0;
    }
  • 相关阅读:
    元类
    多态及多态性和鸭子类型
    类与对象和对应方法、封装
    面向对象与类
    内存管理与正则(re)模块
    Ajax
    Microsoft SQL Server2008安装教程
    兼容所有浏览器的关闭当前页面方法
    如何快速找到指定端口被哪个程序占用并释放该端口(解决bindException)
    MSSQL
  • 原文地址:https://www.cnblogs.com/Hikigaya/p/11422729.html
Copyright © 2020-2023  润新知