zoukankan      html  css  js  c++  java
  • 题解 洛谷 P6078 【[CEOI2004]糖果】

    对于至少 (a) 个,不超过 (b) 个的限制,可以先求出限制不超过 (b) 个的方案数,然后减去限制不超过 (a-1) 个的方案数,即为答案。

    对第 (i) 个糖果罐列出其的生成函数,得:

    [f_i(x)=sum_{j=0}^{m_i} x^j = frac{1-x^{m_i+1}}{1-x} ]

    将每个糖果罐对应的生成函数都卷积起来,得到考虑所有糖果罐的生成函数:

    [f(x)=prod_{i=1}^{n} f_i(x) = frac{prod_{i=1}^n 1-x^{m_i+1}}{(1-x)^n} = left(prod_{i=1}^n 1-x^{m_i+1} ight)sum_{j geqslant 0} inom{n+j-1}{j} x^j ]

    (f(x))(0) 次到 (i) 次项的系数和即为限制不超过 (i) 个的方案数,第一项可以直接 (dfs),后一项可以用 (inom{n}{m} = inom{n}{m-1} + inom{n-1}{m-1}) 来化简。组合数计算时可以扩大模数,然后将计算得出的答案再除回去即可。

    总复杂度为 (O(2^n n))

    (code:)

    #include<bits/stdc++.h>
    #define maxn 15
    #define p 2004
    using namespace std;
    typedef long long ll;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,a,b;
    int m[maxn];
    int C(int n,int m)
    {
        if(n<m) return 0;
        ll x=1,y=1,mod=p;
        for(int i=1;i<=m;++i) x*=i,mod*=i;
        for(int i=n-m+1;i<=n;++i) y=y*i%mod;
        return y/x%mod;
    }
    int dfs(int x,int sum,int type,int tot)
    {
        if(x>n) return C(n+tot-sum,n)*type;
        return (dfs(x+1,sum,type,tot)+dfs(x+1,sum+m[x]+1,-type,tot)+p)%p;
    }
    int main()
    {
        read(n),read(a),read(b);
        for(int i=1;i<=n;++i) read(m[i]);
        printf("%d",(dfs(1,0,1,b)-dfs(1,0,1,a-1)+p)%p);
        return 0;
    }
    
  • 相关阅读:
    Codeigniter:如何写一个好的Model
    CodeIgniter
    CodeIgniter
    Codeigniter CRUD代码快速构建
    html适配Anroid手机
    使用malloc分别分配2KB,6KB的内存空间,打印指针地址
    大话spring.net之IOC
    Spring2.5学习3.3_@Autowire注解实现手动装配
    OPPO通过AWS节约大量成本提供海外服务
    mysql 父子结构排序
  • 原文地址:https://www.cnblogs.com/lhm-/p/13395025.html
Copyright © 2011-2022 走看看