这是一道动态规划题,动态转移方程为 :
$$ans=\sum^{k}_{j=1}{f_{(i-j)}} (f_{0}=1)$$
***
- 记忆化搜索
```cpp
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 100005
#define mod 100003
int n,k;
int bin[MAX];
int f(int i){
if(i==0)return 1;//当i为0时直接返回0
if(bin[i])return bin[i]%mod;//如果之前已经推过f(i)了,就直接调用bin[i]
for(int j=1;j<=k&&i-j>=0;++j)bin[i]=(bin[i]%mod+f(i-j)%mod)%mod;//没推过就做一遍
return bin[i]%mod;
}
int main(){
scanf("%d%d",&n,&k);
printf("%d\n",f(n)%mod);//最后也要%一下
return 0;
}
```
290ms, 7200KB
- 数组递推
```cpp
#include<iostream>
#include<cstdio>
using namespace std;
#define MAX 100005
#define mod 100003
int n,k;
int f[MAX];
int main(){
scanf("%d%d",&n,&k);
f[0]=1;
for(int i=1;i<=n;++i)
for(int j=1;j<=k&&i-j>=0;++j)
f[i]=(f[i]%mod+f[i-j]%mod)%mod;
printf("%d\n",f[n]%mod);
return 0;
}
```
220ms, 944KB
~~还是数组快~~
时间复杂度 O(nk)
$$ans=\sum^{k}_{j=1}{f_{(i-j)}} (f_{0}=f_{1}=1)$$ *** - 记忆化搜索 ```cpp#include<iostream>#include<cstdio>using namespace std;#define MAX 100005#define mod 100003int n,k;int bin[MAX];int f(int x){if(x==1||x==0)return 1;if(bin[x])return bin[x]%mod;for(int i=1;i<=k&&x-i>=0;++i)bin[x]=(bin[x]%mod+f(x-i)%mod)%mod;return bin[x]%mod;}int main(){scanf("%d%d",&n,&k);printf("%d\n",f(n)%mod);return 0;}``` - 数组递推