[BZOJ3028]食物(生成函数)

题目描述

传送门

题目大意:给出了8种食物和其个数的限制,问拿n个食物有多少种方案。

题解

组合问题,需要用到普通型生成函数
先将所有的食物和限制写成生成函数,并利用等比数列的求和公式,忽略母函数的收敛问题求出母函数的闭形式
(1+x2+x4+...)(1+x)(1+x+x2)(x+x3+x5+...)(1+x4+x8+...)(1+x+x2+x3)(1+x)(1+x3+x6+...)
=1x21x1x21x1x31x1x41x11x2x1x211x411x3
=x(1x)4
一个常用的母函数 G(x)=1(x1)m=(1+x+x2+x3+...)m ,那么 G(x) xn 的系数 gn 的值就等价于不定方程 x1+x2+x3+...+xn=m 的非负整数解的个数,这个问题可以用组合数学中的插板法解决,答案是 Cm1n+m1
而操作 xkG(x) 是将序列向右平移k位,并在前k位补0,即 xkG(x)=g0xk+g1xk+1+g2xk+2+...=<0,..0,g0,g1,g2,...>
所以对于这道题来说,求第n位相当于求第n-1位,答案即为 C41n1+41=n(n+1)(n+2)6

代码

#include
#include
#include
#include
#include
using namespace std;
#define Mod 10007
#define inv 1668

int n;

int read()
{
    int x=0;char ch=getchar();
    while (ch<'0'||ch>'9') ch=getchar();
    while (ch>='0'&&ch<='9') x=(x*10+ch-'0')%Mod,ch=getchar();
    return x;
}
int main()
{
    n=read();
    printf("%d\n",n*(n+1)%Mod*(n+2)%Mod*inv%Mod);
}

你可能感兴趣的:(题解,生成函数)