定义
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j]走i步到达点j方案数。
状态转移很好推,为了减少时间,用了点前缀和的思想
#include<bits/stdc++.h>
using namespace std;
// clock_t start, end;
// start = clock();
// end = clock();
// cout << (double) (end - start) / CLOCKS_PER_SEC << endl;
//ios::sync_with_stdio(false);
#define int long long
#define rep(i, x, y) for(int i=(x);i<=(y);++i)
#define dep(i, x, y) for(int i=(x);i>=(y);--i)
#define gcd(a, b) __gcd(a,b)
const long long mod = 1e9 + 7;
const int maxn = 1e4 + 10;
int lowbit(int x) { return x & -x; }
bool ispow(int n) { return (n & (n - 1)) == 0; }//O(1) 判断是否是 2^k(2的k次方)
int read() {
int x = 0, f = 1;
char c = getchar();
while (c < '0' || c > '9') {
if (c == '-') f = -1;
c = getchar();
}
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int dp[maxn][maxn];
int s[maxn];
signed main(){
dp[0][1]=1;
rep(i,1,1000){
s[1]=0;
for (int j = 1; j <= 10000; j++){
s[j]=(s[j-1]+dp[i-1][j]);
}
// cout<<s[100]<<endl;
for(int j=1;j<=10000;j++){
/*for(int k=j-1;k>=1&&(k>=((j&1)==1?(j+1)/2:j/2));k--){
dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
}*/
dp[i][j]=(s[j-1]-s[((j & 1) == 1 ? (j + 1) / 2 : j / 2)-1])%mod;
}
//cout<<i<<' '<<dp[i][40]<<endl;
}
int n, k;
while(cin>>n>>k){
cout<<dp[k][n]<<endl;
}
return 0;
}