123789456ye

已AFO

[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;
}
posted @ 2020-03-21 10:33  123789456ye  阅读(114)  评论(0编辑  收藏  举报