题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4870
题目大意:
题意:一个人注冊两个账号,初始rating都是0,他每次拿低分的那个号去打比赛,赢了加50分,输了扣100分,胜率为p,他会打到直到一个号有1000分为止,问比赛场次的期望。
解题思路:
用E(x。y)表示到(1000, 950)这个状态须要多少场。由于(1000,X) X != 950 这样的情况是不可能发生的。最后E(0,0)就是答案。
E(x1, y1) = E(x2, y2) * p + E(x3, y3) * (1 - p) + 1 是状态,所以能够列出210个方程。用高斯消元就可以。
代码:
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<ctime> #include<iostream> #include<algorithm> #include<string> #include<vector> #include<deque> #include<list> #include<set> #include<map> #include<stack> #include<queue> #include<numeric> #include<iomanip> #include<bitset> #include<sstream> #include<fstream> #define debug puts("-----") #define pi (acos(-1.0)) #define eps (1e-8) #define inf (1<<30) #define seek 31 #define LL long long #define ULL unsigned long long #define maxn 222 #define For(i, n) for (int i = 0; i < n; i++) using namespace std; double a[maxn][maxn] = {0}, ans[maxn] = {0}; bool l[maxn]; int n; inline int solve(double a[][maxn], bool l[], double ans[], const int& n) { int res = 0, r = 0; for (int i = 0; i < n; i++) l[i] = false; for (int i = 0; i < n; i++) { for (int j = r; j < n; j++) if (fabs(a[j][i]) > eps) { for (int k = i; k <= n; k++) swap(a[j][k], a[r][k]); break; } if (fabs(a[r][i]) < eps) { res++; continue; } for (int j = 0; j < n; j++) if (j != r && fabs(a[j][i]) > eps) { double tmp = a[j][i] / a[r][i]; for (int k = i; k <= n; k++) a[j][k] -= tmp * a[r][k]; } l[i] = true, r++; } for (int i = 0; i < n; i++) if (l[i]) for (int j = 0; j < n; j++) if (fabs(a[j][i]) > 0) ans[i] = a[j][n] / a[j][i]; return res; } int cnt = 0, mark[22][22] = {0}; double p; void build() { for (int i = 0; i < 20; i++) { for (int j = 0; j <= i; j++) { int x = mark[i][j]; a[x][x] = 1, a[x][210] = 1; a[x][mark[i][max(0, j - 2)]] -= (1 - p); a[x][mark[max(i, j + 1)][min(i, j + 1)]] -= p; } } } int main () { memset(mark, -1, sizeof(mark)); for (int i = 0; i < 20; i++) for (int j = 0; j <= i; j++) mark[i][j] = cnt++; while(~scanf("%lf", &p)) { memset(a, 0, sizeof(a)); build(); solve(a, l, ans, 210); printf("%.6lf ", ans[0]); } return 0; }