zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    markdown 常用语法
    markdown 转 pdf 方法
    git call failed: [git clone Could not resolve host: git.openstack.org
    从VirtualBox虚拟主机访问NAT客户机的方法
    MVC,MVP 和 MVVM 的图示
    url转义
    Python如何输出包含在对象中的中文字符?
    OpenGL
    AutoHotKey使用:空格键坏了怎么办?
    三联书社推荐好书100本
  • 原文地址:https://www.cnblogs.com/list1/p/10449679.html
Copyright © 2011-2022 走看看