BZOJ1867[Noi1999]钉子和小球

原题链接:钉子和小球 。

先说DP:

DP方程极为简单,如果这个地方有钉子,那么下一层的左右钉子分别继承1/2的概率,如果没有钉子,那么下下层的钉子继承该处全部概率即可。

写出来是这样的:

if(a[i][j] == '*')
    a[i+1][j] += a[i][j] / 2,a[i+1][j+1] += a[i][j]/2;
else 
    a[i+2][j+1] += a[i][j];

当我美滋滋的写完,发现题目要求提交分数。

这还不简单,分母是2^n不就好了吗。
一键三连WA WA WA ~~~

分数结构体:

于是我去找了题解,发现有一个叫做分数结构体的东西。用于处理分数计算。

原题解链接

它的主要东西大概是这个:

struct node
{
    long long up, down;
    node(long long _up = 0, long long _dn = 1) : up(_up), down(_dn){};
    void reduction()
    {
        long long t = gcd(up, down);
        up /= t;
        down /= t;
    }
    void print()
    {
        cout << up << '/' << down;
    }
} f[MAXN][MAXN];
node operator*(node a, node b)
{
    node c = node(a.up * b.up, a.down * b.down);
    c.reduction();
    return c;
}
node operator+(node a, node b)
{
    long long t = gcd(a.down, b.down);
    node c = node(b.down / t * a.up + a.down / t * b.up, a.down / t * b.down);
    c.reduction();
    return c;
}

上面结构体里需要构造函数,否则计算时分母为0就崩了。

下面两个重载运算符。

在赋值的时候,要使用构造函数。不然编译不过去。(c++11是可以的但是BZOJ

一个小坑点:

最后交的时候一直TLE,直到最后发现是在分母相乘时,因为先写分母相乘再约分导致爆long long,顺序调整一下就可以了。

原文地址:https://www.cnblogs.com/Shiina-Rikka/p/11223658.html