10230. 「一本通 6.6 练习 1」牡牛和牝牛

题意

牡 mǔ,畜父也。牝 pìn,畜母也。 ——《说文解字》

约翰要带 $N$ 只牛去参加集会里的展示活动,这些牛可以是牡牛,也可以是牝牛。牛们要站成一排,但是牡牛是好斗的,为了避免牡牛闹出乱子,约翰决定任意两只牡牛之间至少要有 $K$ 只牝牛。请计算一共有多少种排队的方法,所有牡牛可以看成是相同的,所有牝牛也一样,答案对 $5000011$ 取模。

思路

设$f_i$表示当前第$i$头牛放牡牛,那么组合数为$sum_{i-k+1}$。$sum_i=sum_{i-1}+f_i$。最后输出总方案数:$sum_n+1$

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include<algorithm>
#include<bitset>
#include<complex>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<iterator>
#include<limits>
#include<list>
#include<locale>
#include<map>
#include<memory>
#include<new>
#include<numeric>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<typeinfo>
#include<utility>
#include<valarray>
#include<vector>
#include<cstring>
using namespace std;
#define MAXE 400010
#define ll long long
inline ll read(){
char ch=getchar();ll res=0,f=1;
while(ch<'0'ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
return res*f;
}
void write(ll x){
if(x<0) putchar('-'),x=-x;
if(x<10) putchar(x+'0');
else{
write(x/10);
putchar(x%10+'0');
}
}
ll f[100010],sum[100010];
ll n,k;
int main(){
n=read();k=read();
fill(f,f+100001,1);
for(ll i=1;i<=n;i++){
if(i>k){
f[i]+=sum[i-k-1];
f[i]%=5000011;
}
sum[i]=sum[i-1]+f[i];
sum[i]%=5000011;
}
write(sum[n]+1);putchar('\n');
return 0;
}