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\n",(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\n",f[y]); return 0; }
标签:1.0,int,double,robot,Broken,3.0,CF24D,2.0,高斯消 来源: https://www.cnblogs.com/Hikigaya/p/11422729.html