题意:坐标上有一个芯片位于 0 点,可以执行任意数量的移动,每次移动的距离必须是 k 的倍数,每移动一次 k 加上 1,求 1 到 n 每个点有多少种不同方式到达。
思路:当我们要移动到点 j 并且移动距离是 k 的倍数时,那么从可以走到 j 的点到 j - 1中所有 mod k 等于 j mod k的点就能到达 j,所以我们维护一个数组 sum, 存储每个余数分别有多少种方式。然后遍历 k 的值就可以了。
代码:
#include<bits/stdc++.h>
#define pb push_back
#define all(x) x.begin(), x.end()
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 3e5 + 10, P = 1e9 + 7, mod = 998244353;
void solve(){
int n, k;
cin >> n >> k;
vector<int> dp(n + 1), ans(n + 1);
dp[0] = 1;
for(int i = 0; i <= n; i += k++){
vector<int> sum(k);
for(int j = i; j <= n; j++){
int cur = dp[j];
dp[j] = sum[j % k];
(sum[j % k] += cur) %= mod;
(ans[j] += dp[j]) %= mod;
}
}
for(int i = 1; i <= n; i++) cout << ans[i] << " ";
cout <<endl;
}
int main(){
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
//int tt;
//cin >> tt;
//while(tt--) {
solve();
//}
return 0;
}