题面
http://www.lydsy.com/JudgeOnline/problem.php?id=3028
题解
组合问题,考虑普通型生成函数。首先写出每种食物的生成函数:
承德汉堡: 1+x2+x4+...
可乐: 1+x
鸡腿: 1+x+x2
蜜桃多: x+x3+x5+...
鸡块: 1+x4+x8+...
包子: 1+x+x2+x3
土豆片炒肉: 1+x
面包: 1+x3+x6+...
将所有的生成函数乘起来,利用等比数列求和公式,忽略母函数的收敛问题而得到其闭形式(好像很厉害的样子):
现在要求这个鬼东西的第
n
项。我们有两种做法,第一种就是将其
据传说,这个公式可以将生成函数与数列机巧地联系起来,还可以求数列通项等。
于是原式的第
n
项就是求
可是这样为什么是对的呢?这种构造生成函数的合理性和普适性如何才能了解一下?
首先组合只关系数量,排列还关系位置。对于组合问题,构造常生成函数,对于排列问题则需构造指数型生成函数。这里简单说说问什么组合上用常生成函数是对的。
根据我幼稚的理解,由于组合只关注数量,两个函数相乘即相当于卷积。于是所有和为
n
的组合都被卷到了
解决排列的生成函数的原理以后再说。
代码
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#define MOD 10007
using namespace std;
int n, ans;
int Read(){
int x = 0; char ch = getchar();
while(ch < '0' || ch > '9') ch = getchar();
while(ch >= '0' && ch <= '9')
x = ((x << 3) + (x << 1) + ch - '0') % MOD, ch = getchar();
return x;
}
int main(){
n = Read();
ans = n * (n+1) / 2;
if(n % 3 == 0) ans = ans / 3 % MOD * (n+2) % MOD;
if((n+1) % 3 == 0) ans = ans / 3 % MOD * (n+2) % MOD;
if((n+2) % 3 == 0) ans = ans % MOD * ((n+2) / 3) % MOD;
printf("%d\n", ans);
return 0;
}