[BZOJ 3028]食物(生成函数)

本文介绍了一种计算特定数量下食物组合方案数目的算法。针对一组具有特定携带限制的食物种类,通过数学推导得出组合公式,并使用C++实现。该算法适用于解决背包问题中的物品组合计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

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

但是“不定方程的非负整数解的个数”是我一点也不熟悉的问题= =

于是我找到了这个:-wzq

嗯!然后就得到了:这个柿子n次项的系数就是C(3,n+3),因为还乘了一个x所以我们把它平移一位变成了C(3,n+2)

所以说答案就是(n+2)(n+1)n/6

#include<iostream>
#include<cstdio>
#include<cstring>
#define Mod 10007
using namespace std;
int read()
{
    int x=0;char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9'){x=(x*10+c-'0')%Mod;c=getchar();}
    return x;
}
void exgcd(int a,int b,int &x,int &y,int &d)
{
    if(!b){d=a,x=1,y=0;return;}
    exgcd(b,a%b,y,x,d);y-=x*(a/b);
}
int inv(int a,int p)
{
    int d,x,y;exgcd(a,p,x,y,d);
    return (x+p)%p;
}
int main()
{
    int n=read();
    printf("%d\n",((((n+2)*(n+1))%Mod*n)%Mod*inv(6,Mod))%Mod);
    return 0;
}

转载于:https://www.cnblogs.com/Zars19/p/6972487.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值