思路:
将期望dp[x]看成自变量,那么递推式就可以看成方程组,用高斯消元求方程组的解就能求解出期望值
高斯消元求解的过程也是期望逆推的过程,注意边界情况的常数项,是6/d,不是1
代码:
#pragma GCC optimize(2) #pragma GCC optimize(3) #pragma GCC optimize(4) #include<bits/stdc++.h> using namespace std; #define y1 y11 #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb emplace_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pli pair<LL, int> #define pii pair<int, int> #define piii pair<pii, int> #define pdd pair<double, double> #define mem(a, b) memset(a, b, sizeof(a)) #define debug(x) cerr << #x << " = " << x << " "; #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); //head const int N = 105; double A[N][N]; void Gauss(int n) { for(int i = 0; i < n; i ++) { int r = i; for(int j = i + 1; j < n; j ++) if(fabs(A[j][i]) > fabs(A[r][i])) r = j; if(r != i) for(int j = 0; j <= n; j ++) swap(A[r][j], A[i][j]); for(int j = n; j >= i; j --) { for(int k = i + 1; k < n; k ++) A[k][j] -= A[k][i] / A[i][i] * A[i][j]; } } for(int i = n - 1; i >= 0; i --) { for(int j = i + 1; j < n; j ++) A[i][n] -= A[j][n] * A[i][j]; A[i][n] /= A[i][i]; } } int T, n, a, b, to[105]; int main() { scanf("%d", &T); for(int cs = 1; cs <= T; ++cs) { scanf("%d", &n); for (int i = 1; i <= 100; ++i) to[i] = 0; for (int i = 1; i <= n; ++i) scanf("%d %d", &a, &b), to[a] = b; for (int i = 0; i <= 100; ++i) for (int j = 0; j <= 100; ++j) A[i][j] = 0; for (int i = 1; i <= 100; ++i) { A[i-1][i-1] = 1; if(to[i]) { A[i-1][to[i]-1] = -1; } else { int x = min(6, 100-i); for (int j = 1; j <= x; ++j) { A[i-1][i+j-1] = -1.0/x; } if(i < 100) A[i-1][100] = 6.0/x; } } Gauss(100); printf("Case %d: %.10f ", cs, A[0][100]); } return 0; }