• [BZOJ3028]食物


    Description:

    明明这次又要出去旅游了,和上次不同的是,他这次要去宇宙探险!我们暂且不讨论他有多么NC,他又幻想了他应该带一些什么东西。理所当然的,你当然要帮他计算携带N件物品的方案数。他这次又准备带一些受欢迎的食物,如:蜜桃多啦,鸡块啦,承德汉堡等等当然,他又有一些稀奇古怪的限制:每种食物的限制如下:
    承德汉堡:偶数个
    可乐:0个或1个
    鸡腿:0个,1个或2个
    蜜桃多:奇数个
    鸡块:4的倍数个
    包子:0个,1个,2个或3个
    土豆片炒肉:不超过一个。
    面包:3的倍数个
    注意,这里我们懒得考虑明明对于带的食物该怎么搭配着吃,也认为每种食物都是以‘个’为单位(反正是幻想嘛),只要总数加起来是N就算一种方案。因此,对于给出的N,你需要计算出方案数,并对10007取模。

    Hint:

    输入一个数字N,(1<=n<=10^{500})

    Solution:

    生成函数入门题,具体的推导过程:
    首先写出生成函数:

    等比数列求和,化简:

    然后乘起来:

    所以答案就是次数为n的项的系数,即C(n+2,3)
    虽然n很大但模数很小,可以lucas搞一下

    #include<bits/stdc++.h>
    using namespace std;
    const int p=10007;
    int inv[p+5],jc[p+5];
    char s[505];
    
    int main()
    {
    	scanf("%s",s); int n=0,len=strlen(s);
    	inv[0]=inv[1]=jc[0]=jc[1]=1;
    	for(int i=2;i<=p;++i) inv[i]=(p-p/i)%p*inv[p%i]%p,jc[i]=jc[i-1]*i%p;
    	for(int i=2;i<=p;++i) inv[i]=inv[i]*inv[i-1]%p;
    	for(int i=0;i<len;++i) 
    		n=((n*10)+s[i]-'0')%p;
    	n=(n+2)%p;	
    	printf("%d
    ",jc[n]*inv[3]%p*inv[n-3]%p);	
    	return 0;
    }
    
  • 相关阅读:
    Periodic Strings ( UVA
    Digit Counting ( UVA
    Molar mass ( UVA
    Score ( UVA
    Let the Balloon Rise (STL)
    Tree Recovery (STL)
    安卓simpleadapter问题
    安卓活跃手指问题
    python 问题记录
    设计模式笔记
  • 原文地址:https://www.cnblogs.com/list1/p/10449679.html
Copyright © 2020-2023  润新知