[BZOJ3028]食物(生成函数)

来源:互联网 发布:电脑网络映射是断开的 编辑:程序博客网 时间:2024/04/28 22:38

题目描述

传送门

题目大意:给出了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<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;#define Mod 10007#define inv 1668int 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);}
0 0
原创粉丝点击