传送门
题目大意:给出了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+...)
=1−x21−x⋅1−x21−x⋅1−x31−x⋅1−x41−x⋅11−x2⋅x1−x2⋅11−x4⋅11−x3
=x(1−x)4
一个常用的母函数 G(x)=1(x−1)m=(1+x+x2+x3+...)m ,那么 G(x) 中 xn 的系数 gn 的值就等价于不定方程 x1+x2+x3+...+xn=m 的非负整数解的个数,这个问题可以用组合数学中的插板法解决,答案是 Cm−1n+m−1
而操作 xkG(x) 是将序列向右平移k位,并在前k位补0,即 xkG(x)=g0xk+g1xk+1+g2xk+2+...=<0,..0,g0,g1,g2,...>
所以对于这道题来说,求第n位相当于求第n-1位,答案即为 C4−1n−1+4−1=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);
}