CodeForces 24D Broken robot (三对角矩阵消元)

时间:2022-11-16 07:45:34
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
using namespace std;


#define N 1020


int n, m, x, y;

double dp[N][N];

void ele(double x[], double a[], double b[], double c[], double r[]) {
	static double y[N], z[N];
	y[1] = c[1] / b[1], z[1] = r[1] / b[1];
	for(int i = 2; i <= m; ++i) {
		y[i] = c[i] / (b[i] - y[i-1] * a[i]);
		z[i] = (r[i] - z[i-1] * a[i]) / (b[i] - y[i-1] * a[i]);
	}
	x[m] = z[m];
	for(int i = m - 1; i >= 1; --i) x[i] = z[i] - y[i] * x[i + 1];
}

void calc(double x[], double y[]) {
	static double a[N], b[N], c[N], r[N];

	b[1] = 2.0 / 3; c[1] = -1.0 / 3; r[1] = 1 + y[1] / 3;
	for(int i = 2; i < m; ++i) {
		a[i] = -1.0 / 4;
		b[i] = 3.0 / 4;
		c[i] = -1.0 / 4;
		r[i] = 1 + y[i] / 4;
	}
	a[m] = -1.0 / 3; b[m] = 2.0 / 3; r[m] = 1 + y[m] / 3;
	ele(x, a, b, c, r);
}

int main() {
	scanf("%d%d%d%d", &n, &m, &x, &y);
	n = n - x + 1;
	if(m == 1) {
		printf("%d\n", 2 * n - 2);
		return 0;
	}
	for(int i = n - 1; i >= 1; --i) {
		calc(dp[i], dp[i + 1]);
	}
	printf("%.12lf\n", dp[1][y]);
	return 0;
}