本题CF24D,经典高斯解决有后效性DP题。
发现不需要裸的高斯,矩阵中每行只有2到3个数不是零,所以可以$O(m)$消元。
C++ 代码
const int Maxn = 1e3 + 5;
int n, m, x, y;
double f[Maxn][Maxn], g[Maxn][Maxn];
inline void Gauss(int k) {
g[1][1] = g[m][m] = 2, g[1][2] = g[m][m - 1] = -1;
g[1][m + 1] = f[k + 1][1] + 3, g[m][m + 1] = f[k + 1][m] + 3;
for (int i = 2; i < m; i++)
g[i][i - 1] = g[i][i + 1] = -1,
g[i][i] = 3, g[i][m + 1] = f[k + 1][i] + 4;
for (int i = 1; i < m; i++) {
double tmp = g[i + 1][i] / g[i][i];
g[i + 1][i] = 0, g[i + 1][i + 1] -= g[i][i + 1] * tmp;
g[i + 1][m + 1] -= g[i][m + 1] * tmp;
} f[k][m] = g[m][m + 1] / g[m][m];
for (int i = m - 1; i >= 1; i--) f[k][i] = (g[i][m + 1] - f[k][i + 1] * g[i][i + 1]) / g[i][i];
}
signed main(void) {
// file("");
read(n), read(m), read(x), read(y);
if (m == 1) { printf("%d\n", (n - x) * 2); return 0; }
for (int i = n - 1; i >= x; i--) Gauss(i);
printf("%.10lf\n", f[x][y]);
// fwrite(pf, 1, o1 - pf, stdout);
return 0;
}
注意AcWing的输出格式是4位小数,我采用的是CF的spj十位输出!