[CF24D]Broken Robot
题面:Luogu
题解:期望dp+gauss消元
真是古老的题目啊
dp方程很显然:设\(dp_{i,j}\)表示\((i,j)\)走到最后一行的期望步数
第一列时\(dp_{i,1}=\frac{1}{3}(f_{i,1}+f_{i,2}+f_{i+1,1})+1\)
最后一列时\(dp_{i,m}=\frac{1}{3}(f_{i,m}+f_{i,m-1}+f_{i+1,m})+1\)
其他列\(dp_{i,j}=\frac{1}{4}(f_{i,j}+f_{i,j-1}+f_{i,j+1}+f_{i+1,j})+1\)
边界:最后一行\(dp_{n,i}=0\)
于是从第\(n\)行向第1行递推,此时\(dp_{i+1,j}\)都为已知
于是有系数矩阵
\[\left[
\begin{matrix}
-\frac{2}{3} & \frac{1}{3} & 0 & 0 & 0 \\
\frac{1}{4} & -\frac{3}{4} & \frac{1}{4} & 0 & 0 \\
0 & \frac{1}{4} & -\frac{3}{4} & \frac{1}{4} & 0 \\
0 & 0 & \frac{1}{4} & -\frac{3}{4} & \frac{1}{4} \\
0 & 0 & 0 & \frac{1}{3} & -\frac{2}{3} \\
\end{matrix}
\right]
\]
于是我们可以把它消成一个上三角矩阵,具体看代码即可
注意\(m=1\)时要特判一下
#include<bits/stdc++.h>
using namespace std;
inline void read(int& x)
{
x = 0; char c = getchar();
while (!isdigit(c)) c = getchar();
while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
}
#define maxn 1005
#define db double
db a[maxn][maxn], b[maxn], f[maxn];//系数,常数,下一行的dp值
int n, m, x, y;
inline void init()
{
if (m == 1)
{
a[1][1] = -1.0 / 2.0;
b[1] = -f[1] / 2.0 - 1;
return;
}
a[1][1] = a[m][m] = -2.0 / 3.0;
a[1][2] = a[m][m - 1] = 1.0 / 3.0;
b[1] = -f[1] / 3.0 - 1, b[m] = -f[m] / 3.0 - 1;
for (int i = 2; i < m; ++i)
{
a[i][i - 1] = a[i][i + 1] = 1.0 / 4.0;
a[i][i] = -3.0 / 4.0;
b[i] = -f[i] / 4.0 - 1;
}
}
inline void gauss()
{
for (int i = 1; i < m; ++i)
{
db tp = a[i + 1][i] / a[i][i];
a[i + 1][i] = 0;
a[i + 1][i + 1] -= tp * a[i][i + 1];
b[i + 1] -= tp * b[i];
}
f[m] = b[m] / a[m][m];
for (int i = m - 1; i; --i)
f[i] = (b[i] - a[i][i + 1] * f[i + 1]) / a[i][i];
}
int main()
{
read(n), read(m), read(x), read(y);
for (int i = n - 1; i >= x; --i) init(), gauss();
printf("%.10lf", f[y]);
return 0;
}
一切伟大的行动和思想,都有一个微不足道的开始。
There is a negligible beginning in all great action and thought.
There is a negligible beginning in all great action and thought.