#include <bits/stdc++.h>
using namespace std;
const int MOD=1e9+7;
const int N=1e6+5;
int f[N];
int main()
{
int n,k;cin>>n>>k;
f[0]=1;
for(int i=1;i<=n;i++){
f[i]=f[i-1]; // 不放桶:延续前一位的所有方案
if(i-k-1>=0){
f[i]=(f[i]+f[i-k-1])%MOD; // 空出 k 个空位放桶
} else f[i]=(f[i]+1)%MOD; // 前面空位不够,只能放一个桶,相当于加一种方案
}
cout<<f[n];
return 0;
}
f[i]
表示:前 i 个空位的所有合法方案数。
f[0] = 1
:表示 0 个空位时,有 1 种方式(啥都不放)
i 位置不放桶:
f[i] = f[i - 1];
第 i 个空位不放油桶,那就和
i-1
个空位的放法完全一样。所以
f[i]
至少要等于f[i - 1]
。
i 位置放桶:
if (i - k - 1 >= 0) {
f[i] = (f[i] + f[i - k - 1]) % MOD;
在第 i 个位置放一个油桶。前一个油桶最多只能放在第i - k - 1
个位置,所以放一个油桶的方案数等于f[i - k - 1]
如果
i - k - 1 < 0
,说明:
根本没有足够空位留出
k
的间隔。这时候唯一合法的方案就是:只在位置
i
放一个油桶,其它位置不放
总结一句话:
f[i] = 不放桶的方案 + 放桶的方案(考虑空 k 格)