现在的位置: 首页 > 综合 > 正文

2014 Multi-University Training Contest 1 – J Rating

2018年01月12日 ⁄ 综合 ⁄ 共 1745字 ⁄ 字号 评论关闭

题目链接: 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\n", ans[0]);
    }
    return 0;
}

抱歉!评论已关闭.