题目大意:
给你一条射线,他的寿命是 (k) ,每次撞击一个平面,如果穿过,则寿命不减,如果反射,则生成一条新的射线,寿命为之前的射线 -1,问给你 (n) 个平面,一条寿命为 (k) 的射线,最多可以产生多少条新射线。
下面是一个 (n=2,k=3) 的样例。
题解:
容易发现这个是一个 (dp) ,因为你发现推小数据都是十分复杂的,而且状态和状态之间是有重复的,可以相互转移的。
(dp[i][j]) 表示寿命为 (i) 通过第 (j) 个间隔的数量。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
const int mod = 1e9 + 7;
typedef long long ll;
ll dp[maxn][maxn];
int main() {
int T;
scanf("%d", &T);
while (T--) {
int n, k;
scanf("%d%d", &n, &k);
for (int i = 1; i <= k; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = 0;
}
}
// printf("!!!
");
dp[k][1] = 1;
ll ans = 1;
for (int i = k - 1; i >= 1; i--) {
ll sum = 0;
if ((k - i) & 1) {
for (int j = 1; j <= n; j++) {
sum = (sum + dp[i + 1][j]) % mod;
dp[i][j] = sum;
ans = (ans + dp[i][j]) % mod;
}
} else {
for (int j = n; j >= 2; j--) {
sum = (sum + dp[i + 1][j]) % mod;
dp[i][j] = sum;
ans = (ans + dp[i][j]) % mod;
}
}
}
printf("%lld
",ans);
}
return 0;
}