学习算法 题解
aberter0x3f · · 题解
Subtask 2
朴素 DP,设
时空复杂度
re(i, m) f[1][i][1] = 1;
rep(i, 2, n) {
re(c, m) {
re(j, m) {
if (j == c) continue;
re(k, a[j]) f[i][c][1] += f[i - 1][j][k], umod(f[i][c][1]);
}
rep(k, 2, a[c]) f[i][c][k] = f[i - 1][c][k - 1];
}
}
re(i, n) { re(j, a[i]) ans += f[n][i][j], umod(ans); }
Subtask 3
试着把第三维压掉:
时空复杂度
re(i, m) f[1][i] = 1;
rep(i, 2, n) {
re(c, m) {
re(j, m) {
if (j == c) continue;
rep(k, max(1, i - a[j]), i - 1) f[i][c] += f[k][j], umod(f[i][c]);
}
}
}
re(i, m) {
rep(j, n - a[i] + 1, n) { ans += f[j][i], umod(ans); }
}
再加一个用来辅助
时空复杂度
re(i, m) f[1][i] = 1;
rep(i, 2, n + 1) {
re(c, m) {
g[i][c] = g[i - 1][c] + f[i - 1][c], umod(g[i][c]);
if (i - a[c] - 1 >= 1) g[i][c] -= f[i - a[c] - 1][c], dmod(g[i][c]);
}
if (i != n + 1) {
re(c, m) {
re(j, m) {
if (j == c) continue;
f[i][c] += g[i][j], umod(f[i][c]);
}
}
}
}
re(i, m) ans += g[n + 1][i], umod(ans);
Subtask 5
在 subtask 3 的基础上再加一个
时空复杂度
re(i, m) f[1][i] = 1;
rep(i, 2, n + 1) {
re(c, m) {
g[i][c] = g[i - 1][c] + f[i - 1][c], umod(g[i][c]);
if (i - a[c] - 1 >= 1) g[i][c] -= f[i - a[c] - 1][c], dmod(g[i][c]);
h[i] += g[i][c], umod(h[i]);
}
if (i != n + 1) {
re(c, m) f[i][c] = h[i] - g[i][c], dmod(f[i][c]);
}
}
out(h[n + 1])('\n');
Subtask 6
在 subtask 5 的基础上利用滚动数组稍微压一下内存:
时空复杂度
re (i, m)
f[1][i] = 1;
rep (i, 2, n + 1) {
int h = 0;
re (c, m) {
g[i & 1][c] = g[(i & 1) ^ 1][c] + f[i - 1][c], umod(g[i & 1][c]);
if (i - a[c] - 1 >= 1) g[i & 1][c] -= f[i - a[c] - 1][c], dmod(g[i & 1][c]);
h += g[i & 1][c], umod(h);
}
if (i == n + 1) {
out(h)('\n');
} else {
re (c, m)
f[i][c] = h - g[i & 1][c], dmod(f[i][c]);
}
}