【题目描述】
原题来自:USACO 2009 Feb. Silver
牡 mǔ,畜父也。牝 pìn,畜母也。 ——《说文解字》
约翰要带 只牝牛。
请计算一共有多少种排队的方法,所有牡牛可以看成是相同的,所有牝牛也一样,答案对 1 取模。
【输入】
一行,输入两个整数 K。
【输出】
一个整数,表示排队的方法数。
【输入样例】
4 2
【输出样例】
6
【提示】
样例说明
6 种方法分别是:牝牝牝牝,牡牝牝牝,牝牡牝牝,牝牝牡牝,牝牝牝牡,牡牝牝牡。
(母母母母,公母母母,母公母母,母母公母,母母母公,公母母公)
数据范围与提示:
对于全部数据,。
由题意得要在两头公牛之间插入不少于规定数目的母牛,感觉上有点像隔板法,但是母牛的数量不一定,所以说似乎不太好做呢,我想了想也没想到该从何入手,所以就索性滚去看题接了,果然组合数学不是那么好想的呢,还不是因为我太菜了...
简单来说,就是枚举公牛的个数,然后算出此时最少需要多少头母牛(即(i-1)*k),那么此时就是在剩下的n-(i-1)*k个空位中放置这i头公牛,所以写成组合数的形式就是C(n-(i-1)*k,i)
但是注意要开long long哟,一开始我直接用int类型,最后一个点就RE了,后来我机智地把int改成定义long long(我真是太聪明了)就AC啦ㄟ(≧◇≦)ㄏ
![]()
1 #include<bits/stdc++.h>
2 #define int long long
3 using namespace std;
4 int N,p=5000011,k,ans;
5 int mi(int a,int b)
6 {
7 int res=1;
8 while(b)
9 {
10 if(b&1)res=res*a%p;
11 a=a*a%p;
12 b>>=1;
13 }
14 return res;
15 }
16 int c(int n,int m)
17 {
18 if(n<m)return 0;
19 int a=1,b=1;
20 for(int i=n-m+1;i<=n;i++)a=a*i%p;
21 for(int i=2;i<=m;i++)b=b*i%p;
22 return a*mi(b,p-2)%p;
23 }
24 int l(int n,int m)
25 {
26 if(!m)return 1;
27 else return c(n%p,m%p)*l(n/p,m/p)%p;
28 }
29 signed main()
30 {
31 cin>>N>>k;
32 for(int i=0;i<=N;i++)
33 {
34 int j=N-(i-1)*k;
35 if(j<i)break;
36 ans=(ans+l(j,i))%p;
37 }
38 cout<<ans;
39 return 0;
40 }
View Code