【2022 牛客多校】第九场 B 【数组的存取速度related to cache】
链接
https://ac.nowcoder.com/acm/contest/33194/B
题意是n片荷叶排成一排,两个人都可以从1出发,每次可以从第i片荷叶跳到位置在[i+1,i+a[i]]中的荷叶,问两个人跳到n时具有相同步数的概率是多少
思路
dp[k][i]表示跳了k次后到达位置i的概率,依据乘法原理,ans = \(\sum_{i=1}^n dp[i][n]^2\)
枚举i、次数k、下一个位置j是时间复杂度是 \(O(n^3\)) 的(will get a tle)
所以考虑优化时间,在这里我使用了差分数组
p.s.更新时必须让二维数组值频繁更改的那一维放在内循环的位置,这与cache的工作方式有关,如果不这样做仍然会tle
代码如下:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
inline int rd() {
int x = 0;
bool f = 0;
char c = getchar();
for (; !isdigit(c); c = getchar()) f |= (c == '-');
for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return f ? -x : x;
}
#define N 8007
#define mod 998244353
ll inv[N], f[N][N], a[N];
int main() {
inv[0] = inv[1] = 1;
int n = rd();
for (int i = 2; i <= n; ++i) inv[i] = (mod - mod / i + mod) % mod * inv[mod % i] % mod;
for (int i = 1; i < n; ++i) a[i] = rd();
f[0][1] = 1;
for(int k=1;k<n;k++){
for(int i=1;i<n;i++){
ll tem = f[k-1][i] * inv[a[i]] % mod;
f[k][i+1] = (f[k][i+1] + tem) % mod;
f[k][i+a[i]+1] = (f[k][i+a[i]+1] - tem + mod) % mod;
}
for(int i=1;i<=n;i++) f[k][i] = (f[k][i] + f[k][i-1]) % mod;
}
ll ans = 0;
for (int i = 1; i <= n; ++i) ans = (ans + 1ll * f[i][n] * f[i][n] % mod) % mod;
printf("%lld\n", ans);
system("pause");
return 0;
}

浙公网安备 33010602011771号