#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9+7;
unordered_map<long long,long long>mp;
long long n,m;
long long dp(long long n){
if(n<0)
return 0;
if(n<m)
return 1;
if(mp.find(n)!=mp.end())//已经存在过mp[n]的话返回就完事了
return mp[n];
long long mid=n/2;//二分
long long tot=dp(mid)*dp(n-mid)%mod;//一半的每种情况都可以对应另一半的任意一种情况所以可以分解为两半相乘
for(long long i=1;i<m;i++)//dp[n]=dp[n-1]+dp[n-m],状态转移的灵感来源
tot=(tot+dp(mid-i)*dp(n-m-(mid-i))%mod)%mod;//n-m到n这一段的组合情况
mp[n]=tot;//更新
return mp[n];
}
int main(){
scanf("%lld%lld",&n,&m);
mp[0]=0;
mp[1]=1;
printf("%lld",dp(n));
return 0;
}
原文地址:https://www.cnblogs.com/ldudxy/p/10496453.html
时间: 2024-10-30 01:44:23