Rating

来源:互联网 发布:rem px 换算 js 编辑:程序博客网 时间:2024/05/19 02:30

题目链接

  • 题意:
    起始状态是(0,0),每次转移的时候都是对两个数中的较小的数操作。1)以概率p转向(min(a + 50,1000),b)    2)以概率1-p转向(max(a-100,0),b)
  • 分析:
    首先发现状态转移的时候都是以50为单位,所以其实就是除以50之后,即加1或者减2,达到20即可
  • 注意:
    题目精度要求比较高,eps至少要到1e-10
const double eps = 1e-10;double a[22 * 22][22 * 22], x[22 * 22]; //方程的左边的矩阵和等式右边的值,求解之后x存的就是结果int equ, var;                            //方程数和未知数个数int Gauss(){    int i, j, k, col, max_r;    for (k = 0, col = 0; k < equ && col < var; k++, col++)    {        max_r = k;        for (i = k + 1; i < equ; i++)            if (fabs(a[i][col]) > fabs(a[max_r][col]))            max_r = i;        if (fabs(a[max_r][col]) < eps) return 0;        if (k != max_r)        {            for (j = col; j < var; j++)                swap(a[k][j], a[max_r][j]);            swap(x[k], x[max_r]);        }        x[k] /= a[k][col];        for (j = col + 1; j < var; j++) a[k][j] /= a[k][col];        a[k][col] = 1;        for (i = 0; i < equ; i++)            if (i != k)            {                x[i] -= x[k] * a[i][k];                for (j = col + 1; j < var; j++) a[i][j] -= a[k][j] * a[i][col];                a[i][col] = 0;            }    }    return 1;}double P;int s[22 * 22][22 * 22];void build(){    CLR(a, 0); CLR(x, 0);    FE(i, 0, 20) FE(j, i, 20)    {        int cur = s[i][j];        if (~cur)        {            a[cur][cur] = 1;            if (i == 20 || j == 20)                x[cur] = 0;            else            {                int tx = min(i + 1, 20), ty = j;                if (tx > ty) swap(tx, ty);                int nxt = s[tx][ty];                a[cur][nxt] -= P;                tx = max(i - 2, 0); ty = j;                if (tx > ty) swap(tx, ty);                nxt = s[tx][ty];                a[cur][nxt] -= 1 - P;                x[cur] = 1;            }        }    }}void bfs(){    CLR(s, -1);    queue<int> qx, qy;    qx.push(0); qy.push(0);    int cnt = 0;    s[0][0] = cnt++;    while (!qx.empty())    {        int x = qx.front(); qx.pop();        int y = qy.front(); qy.pop();        int tx = min(x + 1, 20), ty = y;        if (tx > ty) swap(tx, ty);        if (!~s[tx][ty])        {            s[tx][ty] = cnt++;            qx.push(tx); qy.push(ty);        }        tx = max(x - 2, 0), ty = y;        if (!~s[tx][ty])        {            s[tx][ty] = cnt++;            qx.push(tx); qy.push(ty);        }    }    equ = var = cnt;}int main(){    bfs();    while (cin >> P)    {        build();        Gauss();        printf("%.6lf\n", x[s[0][0]]);    }    return 0;}


1 0
原创粉丝点击