题意:
题目中说明初始时有一个衰减年龄为
k
k
k的粒子,同时在它的前进方向有
n
n
n个平面,当粒子经过一个平面后,如果粒子的衰减年龄
k
k
k大于1,那么它就会往相反的方向产生一个衰减年龄为
k
−
1
k-1
k−1的粒子。 问这样的一个粒子最终能够产生多少个粒子?
数据范围:
1
<
=
n
,
k
<
=
1000
1 <= n, k <= 1000
1<=n,k<=1000
题意:
d
p
[
j
]
[
i
]
dp[j][i]
dp[j][i]表示,当前粒子衰变年龄为
j
j
j,且当前粒子前还有
i
i
i个平面
d
p
[
j
−
1
]
[
n
−
i
]
dp[j-1][n-i]
dp[j−1][n−i]表示产生一个反向粒子,且衰变一次
d
p
[
j
]
[
i
−
1
]
dp[j][i-1]
dp[j][i−1]表示方向不变,穿过一个平面后还有
i
−
1
i-1
i−1个
故状态转移方程为:
d
p
[
j
]
[
i
]
=
d
p
[
j
−
1
]
[
n
−
i
]
+
d
p
[
j
]
[
i
−
1
]
dp[j][i] = dp[j - 1][n - i] + dp[j][i - 1]
dp[j][i]=dp[j−1][n−i]+dp[j][i−1]
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1010, K = 1010;
const int mod = 1e9 + 7;
int n, k;
int dp[N][K];
void solve() {
scanf("%d%d", &n, &k);
for(int j = 1; j <= k; ++j) dp[0][j] = 1;
for(int i = 1; i <= n; ++i) dp[i][1] = 1;
for(int j = 1; j <= k; ++j)
for(int i = 1; i <= n; ++i) {
dp[i][j] = dp[n - i][j - 1] + dp[i - 1][j];
if(dp[i][j] >= mod) dp[i][j] -= mod;
}
printf("%d\n", dp[n][k]);
}
int main()
{
int T = 1;
scanf("%d", &T);
for(int i = 1; i <= T; ++i) solve();
return 0;
}