题解:B4564 [山东省小学组体验营 2026] 小兔子爬楼梯

· · 题解

题目大意就不多说了,直接讲解题思路。

解题思路

阅读题目我们知道

总方案数(每次跳 1m 级跳完 n 级)- 完全没有逆天一跳的方案数(每次只能跳 1k - 1 级跳完 n 级)= 答案。

那我们就设

答案:(dp[n] − f[n] + MOD) % MOD,加 MOD 防止负数。

转移

dp_i=\sum_{j=1}^m dp_{i-j},\ dp_0=1 f_i=\sum_{j=1}^{k-1} f_{i-j},\ f_0=1 `dp[0]=1` 代表 $0$ 级台阶,$1$ 种方案:什么都不跳。 ::::success[AC code] ```cpp #include <bits/stdc++.h> using namespace std; const int MOD=1e9 + 7; const int MAXN=100005; long long a[MAXN]; long long b[MAXN]; long long sa[MAXN]; long long sb[MAXN]; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n,m,k; cin>>n>>m>>k; a[0]=1; sa[0]=a[0]; for(int i=1;i<=n;++i) { int L=i-m; if(L<=0) { a[i]=sa[i-1]; } else { a[i]=(sa[i-1]-sa[L-1]+MOD)%MOD; } sa[i]=(sa[i-1]+a[i])%MOD; } int t=k-1; b[0]=1; sb[0]=b[0]; for(int i=1;i<=n;++i) { if(t==0) { b[i]=0; } else { int L=i-t; if(L<=0) { b[i]=sb[i-1]; } else { b[i]=(sb[i-1]-sb[L-1]+MOD)% MOD; } } sb[i]=(sb[i-1]+b[i])%MOD; } long long ans=(a[n]-b[n]+MOD)%MOD; cout<<ans<<endl; return 0; } ``` :::: [AC 记录](https://www.luogu.com.cn/record/290955272) 完结撒花~~