zoukankan      html  css  js  c++  java
  • [BZOJ3028] 食物

    明明这次又要出去旅游了,和上次不同的是,他这次要去宇宙探险!我们暂且不讨论他有多么NC,他又幻想了他应
    该带一些什么东西。理所当然的,你当然要帮他计算携带N件物品的方案数。他这次又准备带一些受欢迎的食物,
    如:蜜桃多啦,鸡块啦,承德汉堡等等当然,他又有一些稀奇古怪的限制:每种食物的限制如下:
    承德汉堡:偶数个
    可乐:0个或1个
    鸡腿:0个,1个或2个
    蜜桃多:奇数个
    鸡块:4的倍数个
    包子:0个,1个,2个或3个
    土豆片炒肉:不超过一个。
    面包:3的倍数个
    注意,这里我们懒得考虑明明对于带的食物该怎么搭配着吃,也认为每种食物都是以‘个’为单位(反正是幻想嘛
    ),只要总数加起来是N就算一种方案。因此,对于给出的N,你需要计算出方案数,并对10007取模。

    Solution

    套路题,写出生成函数,并化简为

    [frac{x}{(1-x)^4} ]

    展开为幂级数,运用插板法计算答案,得

    [C_{n+2}^3 ]

    (多此一举地写了高精)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxlen = 2005;
    
    class HP {
    public:
        int len, s[maxlen];
        HP() { (*this) = 0; }
        HP(int inte) { (*this) = inte; }
        HP(const char *str) { (*this) = str; }
        friend ostream &operator<<(ostream &cout, const HP &x);
        HP operator=(int inte);
        HP operator=(const char *str);
        HP operator=(const HP &b);
        HP operator*(const HP &b);
        HP operator+(const HP &b);
        HP operator-(const HP &b);
        HP operator/(const HP &b);
        HP operator%(const HP &b);
        bool operator<(const HP &b);
        bool operator>(const HP &b);
        int Compare(const HP &b);
    };
    
    ostream &operator<<(ostream &cout, const HP &x) {
        for (int i = x.len; i >= 1; i--) cout << x.s[i];
        return cout;
    }
    HP HP::operator=(const char *str) {
        len = (int)strlen(str);
        for (int i = 1; i <= len; i++) s[i] = str[len - i] - '0';
        return *this;
    }
    HP HP::operator=(int inte) {
        if (inte == 0) {
            len = 1;
            s[1] = 0;
            return (*this);
        }
        for (len = 0; inte > 0;) {
            s[++len] = inte % 10;
            inte /= 10;
        }
        return *this;
    }
    HP HP::operator=(const HP &b) {
        len = b.len;
        for (int i = 1; i <= len; i++) s[i] = b.s[i];
        return *this;
    }
    HP HP::operator*(const HP &b) {
        int i, j;
        HP c;
        c.len = len + b.len;
        for (i = 1; i <= c.len; i++) c.s[i] = 0;
        for (i = 1; i <= len; i++)
            for (j = 1; j <= b.len; j++) c.s[i + j - 1] += s[i] * b.s[j];
        for (i = 1; i < c.len; i++) {
            c.s[i + 1] += c.s[i] / 10;
            c.s[i] %= 10;
        }
        while (c.s[i]) {
            c.s[i + 1] = c.s[i] / 10;
            c.s[i] %= 10;
            i++;
        }
        while (i > 1 && !c.s[i]) i--;
        c.len = i;
        return c;
    }
    HP HP::operator+(const HP &b) {
        int i;
        HP c;
        c.s[1] = 0;
        for (i = 1; i <= len || i <= b.len || c.s[i]; i++) {
            if (i <= len)
                c.s[i] += s[i];
            if (i <= b.len)
                c.s[i] += b.s[i];
            c.s[i + 1] = c.s[i] / 10;
            c.s[i] %= 10;
        }
        c.len = i - 1;
        if (c.len == 0)
            c.len = 1;
        return c;
    }
    HP HP::operator-(const HP &b) {
        int i, j;
        HP c;
        for (i = 1, j = 0; i <= len; i++) {
            c.s[i] = s[i] - j;
            if (i <= b.len)
                c.s[i] -= b.s[i];
            if (c.s[i] < 0) {
                j = 1;
                c.s[i] += 10;
            } else
                j = 0;
        }
        c.len = len;
        while (c.len > 1 && !c.s[c.len]) c.len--;
        return c;
    }
    int HP::Compare(const HP &y) {
        if (len > y.len)
            return 1;
        if (len < y.len)
            return -1;
        int i = len;
        while ((i > 1) && (s[i] == y.s[i])) i--;
        return s[i] - y.s[i];
    }
    bool HP::operator<(const HP &b) {
        if (len < b.len)
            return 1;
        if (len > b.len)
            return 0;
        int i = len;
        while ((i > 1) && (s[i] == b.s[i])) i--;
        return s[i] < b.s[i];
    }
    bool HP::operator>(const HP &b) {
        if (len > b.len)
            return 1;
        if (len < b.len)
            return 0;
        int i = len;
        while ((i > 1) && (s[i] == b.s[i])) i--;
        return s[i] > b.s[i];
    }
    HP HP::operator/(const HP &b) {
        int i, j;
        HP d(0), c;
        for (i = len; i > 0; i--) {
            if (!(d.len == 1 && d.s[1] == 0)) {
                for (j = d.len; j > 0; j--) d.s[j + 1] = d.s[j];
                ++d.len;
            }
            d.s[1] = s[i];
            c.s[i] = 0;
            while ((j = d.Compare(b)) >= 0) {
                d = d - b;
                c.s[i]++;
                if (j == 0)
                    break;
            }
        }
        c.len = len;
        while ((c.len > 1) && (c.s[c.len] == 0)) c.len--;
        return c;
    }
    HP HP::operator%(const HP &b) {
        int i, j;
        HP d(0);
        for (i = len; i > 0; i--) {
            if (!(d.len == 1 && d.s[1] == 0)) {
                for (j = d.len; j > 0; j--) d.s[j + 1] = d.s[j];
                ++d.len;
            }
            d.s[1] = s[i];
            while ((j = d.Compare(b)) >= 0) {
                d = d - b;
                if (j == 0)
                    break;
            }
        }
        return d;
    }
    
    char t[505];
    
    signed main() {
        HP n;
        cin>>t;
        n=t;
        cout<<(n*(n+1)*(n+2))/6%10007;
    }
    
    
  • 相关阅读:
    Jzoj4782 Math
    Jzoj4778 数列编辑器
    Jzoj4778 数列编辑器
    力扣算法题—067二进制求和
    力扣算法题—066加一
    最小凸包算法
    力扣算法题—065有效数字
    力扣算法题—064最小路径之和
    力扣算法题—063不同路径2
    力扣算法题—062不同路径
  • 原文地址:https://www.cnblogs.com/mollnn/p/12604573.html
Copyright © 2011-2022 走看看