2014 Multi-University Training Contest 1 - J Rating

来源:互联网 发布:博客网站源码 编辑:程序博客网 时间:2024/05/16 04:16

题目链接: 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;}


0 0
原创粉丝点击