【题目】
Description
约翰要带 只牛去参加集会里的展示活动,这些牛可以是牡牛,也可以是牝牛。牛们要站成一排。但是牡牛是好斗的,为了避免牡牛闹出乱子,约翰决定任意两只牡牛之间至少要有 只牝牛。
请计算一共有多少种排队的方法。所有牡牛可以看成是相同的,所有牝牛也一样。答案对 取模。
Input
一行,输入两个整数 和 。
Output
一个整数,表示排队的方法数。
Sample Input
4 2
Sample Output
6
HINT
种方法分别是:牝牝牝牝,牡牝牝牝,牝牡牝牝,牝牝牡牝,牝牝牝牡,牡牝牝牡
【分析】
牡( )牛,公牛的意思,牝( )牛,母牛的意思
好啦这不是这道题的重点,重点是这道题的算法
不难发现,如果有 头牡牛,一定会有 头牝牛,也就是说牡牛只能在剩下的 个位置上选,方案数就是
那么循环枚举有多少个牡牛,按公式计算答案后累加,到 退出就可以了
最后吐槽一下,数据范围是不是有误啊,数组开小导致 WA 了好久
【代码】
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 1000005
#define Mod 5000011
using namespace std;
int fac[N],inv[N];
int Power(int a,int b)
{
int ans=1;
while(b)
{
if(b&1)
ans=1ll*ans*a%Mod;
a=1ll*a*a%Mod;
b>>=1;
}
return ans;
}
void prework()
{
int i;
fac[0]=fac[1]=1;
for(i=2;i<N;++i) fac[i]=1ll*fac[i-1]*i%Mod;
inv[N-1]=Power(fac[N-1],Mod-2);
for(i=N-2;~i;--i) inv[i]=1ll*inv[i+1]*(i+1)%Mod;
}
int C(int n,int m)
{
return 1ll*fac[n]*inv[m]%Mod*inv[n-m]%Mod;
}
int main()
{
prework();
int n,k,i,num,ans=1;
scanf("%d%d",&n,&k);
for(i=1;i<=n;++i)
{
num=n-(i-1)*k;
if(i>num) break;
ans=(ans+C(num,i))%Mod;
}
printf("%d",ans);
return 0;
}